How to save a base64 image to user's disk using JavaScript?
Solution 1
HTML5 download
attribute
Just to allow user to download the image or other file you may use the HTML5 download
attribute.
Static file download
<a href="/images/image-name.jpg" download>
<!-- OR -->
<a href="/images/image-name.jpg" download="new-image-name.jpg">
Dynamic file download
In cases requesting image dynamically it is possible to emulate such download.
If your image is already loaded and you have the base64
source then:
function saveBase64AsFile(base64, fileName) {
var link = document.createElement("a");
document.body.appendChild(link); // for Firefox
link.setAttribute("href", base64);
link.setAttribute("download", fileName);
link.click();
}
Otherwise if image file is downloaded as Blob
you can use FileReader
to convert it to Base64:
function saveBlobAsFile(blob, fileName) {
var reader = new FileReader();
reader.onloadend = function () {
var base64 = reader.result ;
var link = document.createElement("a");
document.body.appendChild(link); // for Firefox
link.setAttribute("href", base64);
link.setAttribute("download", fileName);
link.click();
};
reader.readAsDataURL(blob);
}
Firefox
The anchor tag you are creating also needs to be added to the DOM in Firefox, in order to be recognized for click events (Link).
IE is not supported: Caniuse link
Solution 2
In JavaScript you cannot have the direct access to the filesystem.
However, you can make browser to pop up a dialog window allowing the user to pick the save location. In order to do this, use the replace
method with your Base64String and replace "image/png"
with "image/octet-stream"
:
"data:image/png;base64,iVBORw0KG...".replace("image/png", "image/octet-stream");
Also, W3C-compliant browsers provide 2 methods to work with base64-encoded and binary data:
Probably, you will find them useful in a way...
Here is a refactored version of what I understand you need:
window.addEventListener('DOMContentLoaded', () => {
const img = document.getElementById('embedImage');
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA' +
'AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO' +
'9TXL0Y4OHwAAAABJRU5ErkJggg==';
img.addEventListener('load', () => button.removeAttribute('disabled'));
const button = document.getElementById('saveImage');
button.addEventListener('click', () => {
window.location.href = img.src.replace('image/png', 'image/octet-stream');
});
});
<!DOCTYPE html>
<html>
<body>
<img id="embedImage" alt="Red dot" />
<button id="saveImage" disabled="disabled">save image</button>
</body>
</html>
Solution 3
This Works
function saveBase64AsFile(base64, fileName) {
var link = document.createElement("a");
document.body.appendChild(link);
link.setAttribute("type", "hidden");
link.href = "data:text/plain;base64," + base64;
link.download = fileName;
link.click();
document.body.removeChild(link);
}
Based on the answer above but with some changes
vengatesh
i am a die hard fan of flex , i have been working with flex since 2010. and i would like to share my knowledge and experience , and also awaiting to get more knowledge.
Updated on June 12, 2021Comments
-
vengatesh almost 3 years
I have converted the source content from the
<img>
html tag to a base64String using JavaScript. The image was displayed clearly. Now I want to save that image to user's disk using javascript.<html> <head> <script> function saveImageAs () { var imgOrURL; embedImage.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA" + "AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO" + "9TXL0Y4OHwAAAABJRU5ErkJggg=="; imgOrURL = embedImage; if (typeof imgOrURL == 'object') imgOrURL = embedImage.src; window.win = open(imgOrURL); setTimeout('win.document.execCommand("SaveAs")', 0); } </script> </head> <body> <a href="#" ONCLICK="saveImageAs(); return false" >save image</a> <img id="embedImage" alt="Red dot"> </body> </html>
This code worked well when I set the image path as source for
<img>
html tag. However, when I pass the source as base64String does not work.How to achieve what I want?
-
Andy E over 12 yearsNote that
atob
andbtoa
have never been part of any standard. They are supported by some standards-compliant browsers, but don't count on it being in all of them. -
John Doe over 12 years@AndyE Correct. That's why you have to perform feature testing before using these methods.
-
vengatesh over 12 years@John Doe : still i couldn't get the save dialogue box for saving the image to user's disk
-
John Doe over 12 years@vengatesh : please see the updated answer. keep in mind that you'll have to specify the correct file extension in order to have your image saved properly.
-
vengatesh over 12 years@John Doe:thanks alot . but it doesn't work with IE ,can we get the file location from from user? can we have the same file format as before?. because all are saved as .part file.
-
John Doe over 12 years@vengatesh : that's right, you have to specify the full filename including an extension (e.g., png). could you please clarify your objective? what do you mean by "can we get the file location from from user? can we have the same file format as before?"?
-
vengatesh over 12 years@Johm Doe:Actually my needs are 1) i want to open a save dialog for storing the image (in html page) 2)the image file was in PNG format before it was converted into base64String, but your code saves the image as eg.part format.here i want the image to be stored in PNG format itself.
-
John Doe over 12 years@vengatesh : This is not my code that proposes you to save file in a *.part format - this is how browser handles the request, since the image is not bytecoded. There is no easy way to achieve a goal. One of possible solutions is configuring a server to respond with certain headers that contain filename and extension - you should google on that matter...
-
benedict_w over 11 years@JohnDoe - Thanks for this answer I used it to build a solution I had to a similar problem and it works perfectly! Only one thing I would like to provide a name for the file download the browser currently it defaults to 'download' (in Chrome anyway). Any ideas?
-
John Doe over 11 years@benedict_w Yeah, I had the same problem. In order to let a browser know how to name a file (including extension) I used a PHP-script that modified
content-disposition
header in an HTTP-response. Hope this helps! -
benedict_w over 11 yearsYeah I also tried this with
header('Content-Disposition: attachment; filename="my-image.png"');
but it didn't work (my image is already generated via a server side script). Did you use the technique here? greenethumb.com/article/1429/… - I don't really want to send my bytecode back to the server if I don't have to! -
John Doe over 11 years@benedict_w I guess it was a similar logic, except for getting data from canvas (just adding the HTTP-headers).
-
John Doe over 8 years@Ankita, I suppose you can use the loaded image source attribute value.
-
Maninder over 8 years@JohnDoe can you tell me how to create data url for image, as I am showing image from database to table. So I have to add functionality to download image. Thanks
-
Eric Hodonsky about 7 years@vengatesh you should accept this answer for the responder. Thanks guys!
-
Alex78191 over 6 yearsNow Safari is supported.
-
heringer over 5 yearsFor me, it worked on Chrome, but it did not work on Firefox. Does anyone face the same problem?
-
Sabrina Luo about 5 yearsjsfiddle is dead :(
-
Pedro Vagner about 5 yearsOn Firefox, the anchor tag must be added to DOM in order to click event work. See stackoverflow.com/q/48642223/1882644