I have spent my entire day trying to delete EXIF data from images with React. I want to do this for try to solve another problem, when user uploads an image with XMP data, apparently AWS WAF blocks it (I didn't have problems with another kind of data, I dind't tried everything tho, but I used an image with camera information and blabla and it worked just fine. Plus, I deleted XMP data from problematic images with a software, and WAF didn't blocked it anymore). So, I want to delete XMP data (author, creator tool, etc.) before send it to server.
I'm using react-dropzone for upload the images, and today I tried different libraries for achieve this, without success. With exifr and exif-js I can see all the EXIF information (including XMP) and specificcaly the data that is causing the error in the upload, but I didn't find a way to remove that from the picture. On the other hand, I used piexifjs and worked fine for delete information, but I couldn't find XMP data!! Just gps, EXIF with camera and picture settings, plus a couple of thing not of my interest. What can I do? I'm able to see this information with exif-js and exifr, but I just can delete things with pixiefjs in which I can't see xmp data.
I do not provide code because it is not an error as such, I want library recommendations or, if exists, a way to configure piexifjs for find this kind of data. exif-js and exifr are for reading, not for removing.
Thanks a lot.
Here would be a sample code of mine:
With a right on the image you should be able to download the image and there should be no exif data included. But I am unsure if there is a better way to do that.
document.getElementById('upload').onchange = function() {
const img = new Image();
img.src = URL.createObjectURL(this.files[0]);
img.onload = function() {
//canvas
const canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(this, 0,0);
//image in html
newImg = document.getElementById('img');
newImg.src = canvas.toDataURL();
newImg.style.width = this.width;
newImg.style.height = this.height;
};
img.onerror = function() {console.error("The file is not an image")};
};
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<input type="file" id="upload">
<img id="img"></img>
<script src="script.js"></script>
</body>
</html>
I'm unsure if it couldn't be simpler, but you could create a canvas with the size of the image, load the image into it, and write the image data from the canvas to a new image file.
Related
Is it possible to get a dataUrl (or simply the SVG source code) of an SVG image which is not inline SVG, but an external SVG file on the same domain?
I had a look at https://github.com/sampumon/SVG.toDataURL, but it only works for inline SVG, not for external SVG files.
To be clear, I am not looking to convert the SVG image to a PNG and then get the PNG's dataUrl, I need to get at the actual SVG code.
The solution would need to be open source and work in most modern browsers.
Here's a minimal version of what I'm trying to do:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function getSvgDataUrl(imgID) {
// FIXME!!!
return dataUrl;
}
function doTheThing() {
result = getSvgDataUrl('foo');
console.write(result);
}
</script>
</head>
<body onload='doTheThing()'>
<img src='myImage.svg' id='foo'>
</body>
</html>
I think the obvious thing to do here is to put the SVG image on a canvas and then get a dataURL from the canvas, like this:
source = new Image();
source.src = 'myImage.svg';
source.onload = function(event){
c = document.getElementById('canvas');
ctx = c.getContext('2d');
ctx.drawImage(source,0,0,116,23);
data = c.toDataURL('image/svg', 1.0);
alert(data);
};
But this gives me a PNG dataURL, not SVG.
I also looked at XMLSerializer, which seemed promising, but I can't work out how to get at the internal SVG. Doing this:
svgImg = document.getElementById('foo');
s = new XMLSerializer();
console.log(s.serializeToString(svgImg));
Just gives the following console output:
<img xmlns="http://www.w3.org/1999/xhtml" src="myImage.svg" id="foo" />
Justin Taddei gave the answer: it's fetch. I get the feeling it was dumb of me not to know this but on the other hand I bet I'm not the only one to get confused by this, so here's the code that worked:
async function getText(file) {
let x = await fetch(file);
let y = await x.text();
console.log(y);
}
getText("myImage.svg");
There's info about fetch here: https://www.w3schools.com/js/js_api_fetch.asp
I am using Rails and I've got a form with a bunch of fields and one of those is image uploading. For now it's just a typical button with multiple option on and it does almost everything I need, but I'd like images' previews (thumbnails) to appear when a user selects images and I'd like to have a "remove" button on these thumbnails in case user decides to remove some image from the collection.
I've tried to use dropzone.js but I dont wanna send form as JSON and I want files to be a part of file input field.
Also I tried to use Jquery File Upload, but I got too confused in all that and so I've tried to use just FileReader API which is what I needed, but I couldnt manage to add remove buttons... Also I wouldnt like to use ajax for that, I think it can be done without it somehow and I dont necesserily need a drag and drop functionality.
Anyway, I think it should be an easy thing to do but I cant find any appropriate tutorials or something for that, so I hope to get some link to a tutorial or just some hint that'll help me to solve the issue.
Thank you.
You can use canvas and FileReader API. Something like this:
$('#yourFileInputField').bind('change', function(e) {
var reader;
reader = new FileReader();
reader.onload = function(event) {
var img;
img = new Image();
img.onload = function() {
var canvas, context;
canvas = $('#canvasId')[0];
context = canvas.getContext('2d');
context.drawImage(img, 0, 0, canvas.width, canvas.height);
};
};
reader.readAsDataURL(e.target.files[0]);
});
When you click on remove just clear canvas and file input field.
I've run into an error that a lot of people seem to have gotten in the past but the explanations are not clear to me. After using the .getImageData() method in my javascript to get the pixel data of a picture that I have stored on my computer and inputed into an img tag in my HTML webpage I get the SecurityError: DOM Exception 18.
I'm simply running an HTMl file in my browser and it is preventing me from getting this stuff done. I've read about making a proxy to get around it or something or hosting the image on my own domain. I don't exactly understand what this means or how to go about doing it. So, it'd be greatly appreciated if anyone could help. I'll input my code here and leave a link to the image as well.
http://i.imgur.com/8UzWlWX.png
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Test</title>
<script>
function putimg() {
var img = document.getElementById('img');
var can = document.getElementById('C');
var ctx = can.getContext('2d');
ctx.drawImage(img, 0, 0);
var position = [];
var imgdata = ctx.getImageData(0,0, img.width, img.height);
var data = imgdata.data;
for (var i = 0; i < data.length; i += 4) {
if (data[i] == 255) {
var vertical = Math.floor((data.indexOf(data[i]) / 4) / 400);
var horizontal = Math.floor((data.indexOf(data[i]) / 4) % 400);
position.push(horizontal, vertical);
}
}
}
ctx.putImageData(imgdata, 0, 0);
}
</script>
</head>
<body onload="putimg()">
<h1>Test</h1>
<img id="img" src="circle-image-alone.png" style="display:none"></img>
<canvas id="C" width="600" height="600"></canvas>
</body>
</html>
EDIT: the file is now in the same folder as the html file, but the same error flag appears
The problem is that this is breaking Same-origin policy. You need to either have imgur relax their Cross-origin sharing or host the image yourself.
If you are running the HTML file directly from the file system on your computer then you can just download the image to the same folder as your html file is in, and reference it like
<img id="img" src="8UzWlWX.png" style="display:none"></img>
Here are the hoops you need to jump through to make it work through a foreign origin like imgur: https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
As you've discovered, your browser considers even your local file system to be a different domain.
So you’re still violating cross-domain even if your image and .html are in the same local directory.
You need a CORS compliant way of loading your image.
Here’s how:
Open up an account on dropbox.com and host your image there.
Be sure to put your image in the “public” folder they set up for you.
They allow cross-domain downloading of their images from your “public” folder.
To get the URL of your dropbox image:
Right-click the image in your public folder and select “copy public link”.
This will put the url into your clipboard where you can paste it into your code.
Then use this code to download your image into the browser in a CORS compliant way:
// download an image from dropbox.com
// in a CORS compliant way
var img=new Image();
img.onload=function(){
ctx.drawImage(img, 0, 0);
}
img.crossOrigin="anonymous";
img.src="dropbox.com/yourDropboxAccount/yourImage.png";
The result is an image that you can fully examine/change/save with:
ctx.getImageData
ctx.putImageData
ctx.toDataURL.
I've web app running. And it uses ajax upload. The issue is recently users are uploading too big images. So it's taking a bit more time. Users are complaining about that. So what I was thinking is this, 'If I somehow crop and resize the image via js and then send it to the server via ajax upload then the time will be reduced'. So is there any way to do that? Any idea for it?
A solution is to use modern ways like FileReader and Canvas (But this works only on the latest modern browsers).
http://caniuse.com/filereader
http://caniuse.com/canvas
In this example i show how to let the client resize an image before uploading by setting a max width & height mantaining aspect ratio.
In this example max widthHeight = 64;
your final image is c.toDataURL();
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
var h=function(e){
var fr=new FileReader();
fr.onload=function(e){
var img=new Image();
img.onload=function(){
var MAXWidthHeight=64;
var r=MAXWidthHeight/Math.max(this.width,this.height),
w=Math.round(this.width*r),
h=Math.round(this.height*r),
c=document.createElement("canvas");
c.width=w;c.height=h;
c.getContext("2d").drawImage(this,0,0,w,h);
this.src=c.toDataURL();
document.body.appendChild(this);
}
img.src=e.target.result;
}
fr.readAsDataURL(e.target.files[0]);
}
window.onload=function(){
document.getElementById('f').addEventListener('change',h,false);
}
</script>
</head>
<body>
<input type="file" id="f">
</body>
</html>
In the canvas part of the code you can also add a cropping function.
Edit as asked in the comments
c.toDataURL();
is the image base64_string you can store it in a hidden input,append to a new FormData() or wherever you want.
on the server
$data=explode(',',$base64_string);
$image=base64_decode($data[1]);
write to file
$f=fopen($fileName,"wb");
fwrite($f,$image);
fclose($f);
or
$gd=imagecreatefromstring($image);
you can also store the whole base64 image string in the database and always use that.
I would like to be able to download a Html5 canvas element as an image with the file extension with Javascript.
The CanvasToImage library does not seem to be able to achieve this.
Here is my code so far which you can see at this JsFiddle.
<div id="canvas_container">
</div>
<p>
create
download
</p>
$("#create_image").click(function() {
var cnvs = createSmileyOnCanvas();
$('#canvas_container').append(cnvs);
});
$("#download_image").click(function() {
var img = $('#smiley_canvas').toDataURL("image/png");
var uriContent = "data:application/octet-stream," + encodeURIComponent(img);
window.open(uriContent, 'download smiley image');
});
function createSmileyOnCanvas() {
var canvas = document.createElement('canvas');
canvas.id = 'smiley_canvas';
var ctx = canvas.getContext('2d');
// Draw shapes
ctx.beginPath();
ctx.arc(75,75,50,0,Math.PI*2,true); // Outer circle
ctx.moveTo(110,75);
ctx.arc(75,75,35,0,Math.PI,false); // Mouth
ctx.moveTo(65,65);
ctx.arc(60,65,5,0,Math.PI*2,true); // Left eye
ctx.moveTo(95,65);
ctx.arc(90,65,5,0,Math.PI*2,true); // Right eye
ctx.stroke();
return canvas;
}
This seems to work for me:
<a id="downloadImgLink" onclick="$('#downloadImgLink').attr('href', canvas.toDataURL());" download="MyImage.png" href="#" target="_blank">Download Drawing</a>
In order to force/suggest a file name in the browser's download dialog, you would need to send the Content-Disposition: attachment; filename=foobar.png header.
This is not possible to do via window.open, so you're out of luck unless there are some browser-specific hacks for this.
If you really need the filename, you could try using the new download attribute in a, <a href="put stuff here" download="filename here">. It isn't very widely supported yet though.
Another alternative would be to first submit the data to the server using ajax, then redirect the browser to some server-side script which would then serve the data with the correct header.
Hi i have created a jquery plugin which will let you do the same task with ease but it also make use of php to download the image. let me explain how it works
Plugin has 2 sub function that you can call independently to add image to the canvas and the other one is to download the current image lying on the canvas.
Add image to the canvas
For this you need to pass the id of the canvas element and the path of the image you want to add
download image from the canvas
For this you need to pass the id of the canvas element
$('body').CanvasToPhp.upload({
canvasId: "canvas", // passing the canvasId
image: "455.jpg" // passing the image path
});
// downloading file
$('#download').click(function(){
$('body').CanvasToPhp.download({
canvasId: "canvas" // passing the canvas id
}); //
});
First you need to download the plugin file which you can find here http://www.thetutlage.com/post=TUT213
I have also created a little demo http://thetutlage.com/demo/canvasImageDownload