0

At first, add the generated dataURL to the href attribute of the <a> tag. On some browsers, this alone will not trigger a download, but open the linked image in a new page.

Download dialog for a base64 image:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...." class="image" />

Based on above example, convert the MIME type of the DataURL to this:

<a href="data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUg....">Download</a>

Telling the browser that the data is application/octet-stream, it will ask you to save it on your hard-disk.


Specifying a filename:

As Adnan said in the comments below (@Adnan: I upvoted yours as this is actually a big problem): There is no standard way to define a filename using this method, but there are two approaches which might work in some browsers.

A) The download-attribute

<a download="image.png" href="...">

(Introduced by Google Crome)

B) Defining HTTP-headers within the data-URL
headers=Content-Disposition: attachment; filename=image.png

<a href="data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=image.png;base64,iVBORw0KGgoAAAA">

(Worked at least in some older versions of Opera) Here is some discussion about this.

Looking into the Bug/Feature-Tracking systems of the major browsers shows that defining a filename is a quite big wish of the community. Maybe we will see a cross-browser compatible solution in near future! ;)


Save RAM and CPU ressources:

If you don't want to bloat the RAM of your visitor's browser, you can also generate the data-URL dynamically:

<a id="dl" download="Canvas.png">Download Canvas</a>
function dlCanvas() {
    var dt = canvas.toDataURL('image/png');
    this.href = dt;
};
dl.addEventListener('click', dlCanvas, false);

This way, your canvas may still be shown as an image file by your browser. If you want to increase the probability to open a download dialog, you should extend the function above, so that it does the replacement as shown above:

function dlCanvas() {
    var dt = canvas.toDataURL('image/png');
    this.href = dt.replace(/^data:image\/[^;]/, 'data:application/octet-stream');
};
dl.addEventListener('click', dlCanvas, false);

At last, you could even add the HTTP-header to make extra shure that most browser offer a valid filename to you! ;)


FULL EXAMPLE:
var canvas = document.getElementById("cnv");
var ctx = canvas.getContext("2d");

/* FILL CANVAS WITH IMAGE DATA */
function r(ctx, x, y, w, h, c) {
  ctx.beginPath();
  ctx.rect(x, y, w, h);
  ctx.strokeStyle = c;
  ctx.stroke();
}
r(ctx, 0, 0, 32, 32, "black");
r(ctx, 4, 4, 16, 16, "red");
r(ctx, 8, 8, 16, 16, "green");
r(ctx, 12, 12, 16, 16, "blue");

/* REGISTER DOWNLOAD HANDLER */
/* Only convert the canvas to Data URL when the user clicks. 
   This saves RAM and CPU ressources in case this feature is not required. */
function dlCanvas() {
  var dt = canvas.toDataURL('image/png');
  /* Change MIME type to trick the browser to downlaod the file instead of displaying it */
  dt = dt.replace(/^data:image\/[^;]*/, 'data:application/octet-stream');

  /* In addition to <a>'s "download" attribute, you can define HTTP-style headers */
  dt = dt.replace(/^data:application\/octet-stream/, 'data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=Canvas.png');

  this.href = dt;
};
document.getElementById("dl").addEventListener('click', dlCanvas, false);
<canvas id="cnv" width="32" height="32"></canvas>
<a id="dl" download="Canvas.png" href="#">Download Canvas</a>
RachitD
  • 19
  • 4
  • IE doesn't support the `download` attribute on anchors. As a workaround, you can use Eli Grey's FileSaverJS in IE: https://github.com/eligrey/FileSaver.js/ – markE Sep 26 '15 at 04:16

1 Answers1

-1

I succeed with this approach.

Basically you use this. https://github.com/eligrey/FileSaver.js/

Then generate blob data from base64 string. http://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript

I close this issue because there is alternative way.

You can use above github as a reference. U will get a good idea about it