hotips
hotips

Reputation: 2631

How to save a png from javascript variable

I have an image encoded in base64 in a javascript variable : data:image/png;base64, base64 data

[EDIT] I need to save that file to disk without asking to the visitor to do a right click [/EDIT]

Is it possible ? How ?

Thanks in advance

Best regards

Upvotes: 25

Views: 42982

Answers (10)

Nate
Nate

Reputation: 1276

The accepted solution seems to have a limitation for large data. If you're running into this (instead of the downloaded file's name, I see "download" and "Failed - Network error" in Chrome), here's what I did in order to download a 2mb file:

const blob = await (await fetch(document.getElementById('canvasID').toDataURL())).blob();
const file = new File([blob], {type:"image/png", lastModified: new Date()});
var a = document.createElement('a');
a.href = window.URL.createObjectURL(file);
a.download = 'image.png';
a.click();

Upvotes: 0

Footer
Footer

Reputation: 139

You can make this file as blob on the server and use setTimeout function in order to fire the download.

Upvotes: 0

malber
malber

Reputation: 1073

I am surprised nobody here mentioned using HTML5 blobs together with a couple of nice libraries.

You first need https://github.com/eligrey/FileSaver.js/ and https://github.com/blueimp/JavaScript-Canvas-to-Blob.

Then you can load the image into a canvas

base_image = new Image();
base_image.src ='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';

the canvas into a blob

var canvas = document.getElementById('YourCanvas');
context = canvas.getContext('2d');
// Draw image within
context.drawImage(base_image, 0,0);

and finally save it

x_canvas.toBlob(function(blob) {
saveAs(blob, "screenshot.png");
}, "image/png");

FF is not fully supported but at least you get a separate page with the image.

Check this out: http://jsfiddle.net/khhmm/9/

EDIT: this is not compatible with Safari / Mac.

Upvotes: 6

davoclavo
davoclavo

Reputation: 1442

I know this question is 2 years old, but hopefully people will see this update.

You can prompt the user to save an image in a base64 string (and also set the filename), without asking the user to do a right click

var download = document.createElement('a');
download.href = dataURI;
download.download = filename;
download.click();

Example:

var download = document.createElement('a');
download.href = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
download.download = 'reddot.png';
download.click();

In order to trigger a click event using Firefox, you need to do what it is explained in this SO answer. Basically:

function fireEvent(obj,evt){
  var fireOnThis = obj;
  if(document.createEvent ) {
    var evObj = document.createEvent('MouseEvents');
    evObj.initEvent( evt, true, false );
    fireOnThis.dispatchEvent( evObj );
  } else if( document.createEventObject ) {
    var evObj = document.createEventObject();
    fireOnThis.fireEvent( 'on' + evt, evObj );
  }
}
fireEvent(download, 'click')

As of 20/03/2013, the only browser that fully supports the download attribute is Chrome. Check the compatibility table here

Upvotes: 47

ionutcib
ionutcib

Reputation: 267

I think you can do it something(maybe not only with javascript...xul programming needed). There are Firefox addons that save images to a folder(check Firefox addons site)

Upvotes: 0

user323094
user323094

Reputation: 3653

As other answers already stated, you cannot do it only with javascript. If you want, you can send the data (using normal HTTP POST) to a PHP script, call header('Content-type: image/png') and output the decoded image data to the page using echo base64_decode($base64data).

This will work just as if user clicked on an image and open it or prompt him to save the file to disk (the normal browser's save file dialog).

Upvotes: 3

BalusC
BalusC

Reputation: 1108632

... without asking to the visitor anyhing ... Is it possible?

No, that would have been a security hole. If it was possible, one would be able to write malware to the enduser's disk unaskingly. Your best bet may be a (signed) Java Applet. True, it costs a bit of $$$ to get it signed (so that it doesn't pop security warnings), but it is able to write data to enduser's disk without its permission.

Upvotes: 6

oezi
oezi

Reputation: 51797

with javascript, you can't. the only real possibility i can think of will be a java-applet, but maybe (i don't know how long that image should be saved) you could simply add an img-tag with you png and force caching (but if the user deletes his cache, the image will be gone).

Upvotes: 1

Julio Santos
Julio Santos

Reputation: 3895

I think it's possible with JavaScript if you use ActiveX.

Another possibility is to make the server spit out that file with a different mime type so the browser asks the user to save it.

Upvotes: 0

Jerod Venema
Jerod Venema

Reputation: 44632

It's not possible.

If it was, browsers would be massively insecure, being able to write random data to your hard disk without user interaction.

Upvotes: 2

Related Questions