Check out my
new book!
HTML5 Games book
Canvas2Image - or how to save canvas data to an image file
So you've created a masterpiece using the canvas element, making sexy boxes, polygons and lines, and now you want to save your piece of art.
- but there's no "Save as..." option when you right click. Bugger. Enter Canvas2Image!


Luckily, it turns out we can use the toDataURL() method, data: URI's and a bit of Javascript to allow saving the canvas image.

Canvas2Image is a little library which can be used to easily either save the canvas as PNG, JPEG or BMP, or create an image element with the image data. PNG is supported by Firefox, Opera and Safari with the latest WebKit nightly. JPEG is only available in Firefox.

BMP is not natively supported in any of the browsers, so to make things more interesting, we have implemented our own BMP function which will read the raw canvas pixel data using getImageData(), setup a simple BMP file structure in Javascript, base64 encode it and stick it in a data: uri.

Demo here: http://www.nihilogic.dk/labs/canvas2image/
⇓ 71 comments Anonymous

Cool. Do you know if something similar is possible for SVG or VML?
/ Fredrik

April 9, 2008 at 12:54 AM
CupBoy

No, I don't think it is. Would be neat if it was, though, then excanvas could be made saveable too.

April 9, 2008 at 4:11 AM
Anonymous

Ok. I guess you could technically/theoretically write an SVG parser & renderer that outputted base64 ;)
/ Fredrik

April 9, 2008 at 7:35 AM
Mathieu 'p01' Henri

SVG 1.1 requires UAs to support SVG in (x)HTML Image Element. There it is straightfoward to draw an SVG element onto a Canvas using CanvasContext.drawImage( SVGElement, 0, 0 );

Seeing how much SVG implementors choke on the spec and get it wrong, you probably don't want to implement your own interpreter ;)

April 9, 2008 at 8:50 AM
Anonymous

Hi... Really cool stuff.... Do you think it's possible to define different brushes eg. from images or vector data?

April 9, 2008 at 9:06 AM
CupBoy

@anon: Sure. The drawing part was just done for giggles and not to make a real drawing app, as this is more about saving images than drawing.
I'm sure there are better and nicer canvas paint applications out there.

April 9, 2008 at 10:53 AM
antimatter15

If you combine this with http://fuchsia-design.com/CanvaSVG/, you effectively have a way to convert SVG to Canvas to Bitmap.

Example: http://antimatter15.110mb.com/misc/svg2bitmap/index.xhtml

April 9, 2008 at 4:45 PM
Anonymous

@anon: Grafio's Artist's Sketchbook is a nice Canvas based drawing widget.

April 10, 2008 at 12:57 AM
mud

In OSX, when downloading these files, the suffix appended is .exe... which is kinda confusing for the user. Changing it to "image/octet-stream" seems to work. But maybe that's completely invalid.

April 18, 2008 at 10:32 AM
CupBoy

@mud: Thanks, I'll try and change that.

April 18, 2008 at 9:50 PM
TjerkW

What would be cool if you could somehow add this to a web-form and submit the image to the server... that would be possible not?

Just send the imagedata to the server... dman that would be cool. Users can add self-drawn-images instead of plain text. always funny

I only need a simple canvas-paint / editor now..

April 19, 2008 at 1:41 AM
Breton Slivka

Couldn't you go one step further and perform the conversion on right mouse click, and then reset when the context menu is dismissed? Then you eliminate an extra step for the user, and it looks like you can saveAs a canvas.

May 28, 2008 at 10:03 PM
lorlarz

Someone needs to put this image saving capability together with something like http://mynichecomputing.org/sharedDraw/ using mySQL database for storage and get a super modified version of this shared whiteboard program. Get your own copy of the complete kit of source code for this here: http://mynichecomputing.org/roughDrawKit.zip Let me know at lorlar AT gmail dot com if you do this just-proposed version

May 1, 2009 at 2:41 PM
Jacob Seidelin

@lorlarz: Anyone is free to take the code and use it (it's MIT licensed) for whatever. I don't have time right now to work more on this, though.

May 2, 2009 at 2:48 AM
Sebastian Sanchez

so, can we save the canvas on a server directory (777)?

October 21, 2009 at 9:09 AM
Anonymous

Hey,
I opened the canvas area in a popup. The pop-up size is 700 X 700 and the canvas dimensions are 600 X 300. When I use the mouse to draw inside the area, I'm not able to utilize the full height of the canvas. Also the mouse positions seems to be screwed up. Any idea? Do I have to modify the mouse event functions to so that mouse movements are captured correctly

March 9, 2010 at 1:26 PM
Paul Hayes

is there any way to write the image to a file on the host server rather than have it open as a file download within the browser?`

April 26, 2010 at 6:34 AM
Sam Dutton

Is there a way to get this to work with Chrome?

May 21, 2010 at 5:48 AM
smokinguns

I'm able to save the image to a file on a server. How do I prevent users from saving a blank image(if they leave the canvas blank and save it)?

May 24, 2010 at 8:49 AM
Oliver George

Has anyone tried posting the canvas image back to the server in a form?

May 24, 2010 at 3:54 PM
smokinguns

@Oliver George:
It's very easy. I'm using jQuery to serialize the form input. Before sending the form input to the server(I'm using Ajax to do this ), I append the canvas image data to it.
This is how I'm doing it:
var formInput= jQuery("#ID_of_the_form").serialize();
// Now append canvas image-------
formInput+="&img="+oCanvas.toDataURL('image/jpeg');//saving in JPEG format

// This is the PHP Code------------
$image = str_replace(" ", "+", $_POST["img"]);
$data = substr($image, strpos($image, ","));

// Save the image to a file ------
$filename="myImage.jpg";
$file = fopen("Your/images/folder/".$fileName, "wb");
fwrite($file,base64_decode($data));
fclose($file);

May 25, 2010 at 12:33 PM
Sam Dutton

Any joy with this?:

>> It would be really neat if somehow a filename could be attached to the data, but I've found no way to do that. For now, you have to specify the filename yourself. <<

May 27, 2010 at 2:08 PM
Alex

is there any plan to make it work in chrome?

June 7, 2010 at 11:58 PM
Anonymous

I use it for converting a graph ( with flot - jquery plugin).
I just use the png conversion, because others doesn't look good, which works for me in FF and Chrome, but not IE.
Would be nice if it would work in IE too. isn't it possible with the excanvas.js and some ie related fixes`?

June 20, 2010 at 7:38 AM
Anonymous

Error: oScaledCanvas.toDataURL is not a function

Where is the toDataURL function defined. I keep getting this error and can't seem to crack it.

July 1, 2010 at 1:05 PM
Anonymous

I also get the same error, tried opera 10.6 and ff 3.6.6, both with "PNG" and "JPEG"

Error: oScaledCanvas.toDataURL is not a function.

anyone has any clue ?

July 15, 2010 at 11:00 AM
Anonymous

Hi !
I have win7 + Firefox 3.6.8. I'm testing the
Canvas2Image.saveAsPNG() function, and cannot find a Name for the PNG file. The function write a file with random name, and .part extension. Can anyone help ?

August 15, 2010 at 11:59 PM
Anonymous

FF 3.6.8 here as well and getting the toDataURL is not a function.

Doesn't work on Chrome or Safari either. Did it get stealth nerfed for security issues or is the function inherently useless because the end user has to turn something on?

August 17, 2010 at 10:00 AM
Anonymous

Can you add the ability to specify the default filename in javascript when you save?

August 24, 2010 at 2:03 AM
Hristo Yankov

I just would like to mention - this plugin will not work for a canvas on which was performed a drawImage(...) call, where the image was outside your domain.

In other words, if you needed to drawImage on your canvas, and this image was from another domain, you can't export your canvas to an image later.

This is 'thanks' to the same-origin policy and more specifically, the browser will prevent you from doing getImageData().

December 16, 2010 at 5:31 AM
Anonymous

Does anybody know how to save only a particular part of the canvas, by modifying the file canvas2image.js or base64.js?... I don't need to save the whole thing

January 28, 2011 at 4:02 PM
Anonymous

Any news about canvas behaviour and same-origin policy?
Did someone find a work around ?

February 22, 2011 at 12:59 AM
Valentina

Is there a way to specify the filename of the image before saving it locally?

May 4, 2011 at 7:01 AM
Bert Peters

Nice script, but please let it be noted that base64 libraries aren't needed.
Simply btoa and atob do just fine.

July 8, 2011 at 12:17 PM
Meysam

filename is always very long and contains random characters then .part

July 12, 2011 at 8:06 PM
Mithilesh

Hello,
I am not able to save on IPAD. It gives me prompt that Safari cannot download this file. Is there any solution to save canvas as image on Ipad ??

July 19, 2011 at 6:42 AM
Rohanb

hii..I want to save image on usb..How can i achieve this??
please help

July 26, 2011 at 2:36 AM
Overklog

hi

Anyone know how to get the File to save a spesific file name or even just to make the default save as .jpeg or .PNG and not .part?

September 20, 2011 at 3:05 PM
Brigitte & Marc-André

is it possible to make it work with the help of explorercanvas... because now it dont work with IE

October 3, 2011 at 8:06 PM
David Guinnip

Has anyone had any luck saving a WebGL canvas using this library?

November 4, 2011 at 1:27 PM
ruslanb

can I use it in a gwt app?

November 18, 2011 at 6:33 PM
ldness

The method doesn't seem to work on IE 9 (though most canvas-related operations I have used do). The statement

document.location.href = strData

in saveFile() generates the message

The data area passed to a system call is too small.

I think the problem is that IE doesn't support a URL over 2048 bytes long, as described in http://support.microsoft.com/kb/208427 .

I am not sure that there is a solution that still results in a direct download of the file. If you know of one, please let me know.

December 7, 2011 at 7:49 AM
Bade.I.

For the filename issue, add the download attribute to your \ tag. i.e. <a download="test.png" href="javascript:document.getElementById(<canvas_div_id>).toDataURL('image/png').replace(image/png);"

Simple as pie :)

March 28, 2012 at 6:51 AM
Robbin Petter

hi,
so nice post....

Canvas prints are wrapped on 3/4" or 1 1/2" thick high quality wooden frames. We only use premium qaulity wood, for unsurpassed quality.

Canvas prints

April 13, 2012 at 7:33 AM
FlaKa

it saves a file with no extension, and when i save it in my ipad my app file can't open it, how can i solve this??

April 16, 2012 at 12:49 PM
Tiago Pedras

Hi! I've been getting these "Security error" warnings on both Firefox and Chrome. Have any idea what this is about?
I was just doing a straight console.debug out of the canvas.toDataURL function

May 3, 2012 at 4:16 AM
Tiago Pedras

Hi! I've been getting these "Security error" warnings on both Firefox and Chrome. Have any idea what this is about?
I was just doing a straight console.debug out of the canvas.toDataURL function

May 3, 2012 at 4:16 AM
Nur

amazing! thank you

May 3, 2012 at 8:06 AM
Yaseen Abbas

Blog design is an important aspect to attract visitors.

online sweepstakes
church software
blackjack software

May 8, 2012 at 10:31 PM
Jonas Otten

Hey there =)
Have an Issue with Androidphones
Everytime the finger leaves the touchscreen the script draws a line back to the centre of the field.
Apple just works fine.
Is it a known issue?

June 25, 2012 at 3:58 AM
Audrey Maniez

Hello,
thanks for that, nearly what i was looking for.

Does a background image on the canvas can be rendered in the png file generated ?

August 7, 2012 at 4:39 AM
Jakob Kaltenbrunner

http://greenethumb.com/article/1429/user-friendly-image-saving-from-the-canvas/

That's the solution for the filename and .part problem I was looking for, maybe others will also be looking for something like that

August 19, 2012 at 1:29 AM
Jacques Mulder

When i click on save. I get a .part file not a jpg or png on all three save buttons.
Firefox 14

September 19, 2012 at 4:54 AM
Jacques Mulder

oh I see some has had the same problem already.
I'll check the link

September 19, 2012 at 4:55 AM
тупомерка

I think, alpha channel saved with bugs for png format. (artefacts) Plaese check this version and correct.
Thx!

October 2, 2012 at 3:07 AM
Martin

Thanks a lot man! I especially appreciate your effort to transform the image data to bitmap, this is very useful for mobile browsers that don't support toDataUrl (like android < 3.0). Danke!

October 9, 2012 at 5:16 AM
Damien Golding

Hi, please let me know how to initiate the download with JavaScript from canvas with a button as show in the example.

Thanks

November 8, 2012 at 1:02 AM
LiChenbo

Very appreciate yoru work, thanks.

November 12, 2012 at 10:36 AM
Joey Padasian

Hi Jacob, really like this site, you've got some great knowledge here.

I've been trying to get this canvas2image to work, but it seems as though it wont save or download an image if you draw a png image into the canvas?

Has anyone else tried this? As I can't seem to get it to work.

December 20, 2012 at 6:30 PM
Farid Ghazi

exception inside

at this point:
// sends the generated file to the client
var saveFile = function(strData) {
document.location.href = strData;
}

My call:



function captureImage() {
var video = document.getElementById("Video1");
var ctx = document.getElementById('canvas').getContext('2d');
ctx.canvas.width = video.clientWidth;
ctx.canvas.height = video.clientHeight;
ctx.drawImage(video, 0, 0, 32, 32);

var oCanvas = document.getElementById("canvas");
Canvas2Image.saveAsPNG(oCanvas);
// will prompt the user to save the image as PNG.
}

March 30, 2013 at 5:33 PM
Farid Ghazi

I find canvaimage2 very importante and nice to quickly capture & save image from video, could you tell me please where is the problem in my last post. Than you

March 31, 2013 at 10:42 AM
kevin

I think you can now get it to use a filename in Chrome at least.
http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download

April 6, 2013 at 6:12 AM
Waqar Haider

Hello Everyone,
I am facing problem in running this code, though I added both libraries (base64 and canvas2image) but still facing failure
anybody please provide me complete working source code of this example.
waqar.sign@gmail.com
Thanx in advance

May 13, 2013 at 6:21 AM
Unknown

This Canvas2Image library works fine with my laptop, but when I run it on my Android tablet, it just downloads a random file with .bin extension and when I try to open this file, it just fails to open. Can somebody tell me how I can accomplish this in Android devices?

May 29, 2013 at 7:34 AM
Zakaria Gaizi

Hello, I've tried your tutorial, and it works perfectly (saving images and generating), I just want to know, when generating images, how can I save them on the server (with the name I want)??
Thank you very much.

June 20, 2013 at 6:33 AM
economy4all

The generated image is not copy/pastable to Word (though you can paste it in paint.net)
Does anyone have an idea how to make this image copy pastable to Word

August 20, 2013 at 12:08 AM
myaccount

good

December 3, 2013 at 6:05 AM
Ben Nitti

Thanks for setting up this demo. I really need to find a way to simply take some existing HTML and turn that into an image, I tried tinkering with this code but was not able to get that to work -- do you know how this could be done?

Thanks, Ben

December 10, 2013 at 11:04 AM
Maxim Bogdanov

Hi. I can't find answer on my question. I'm use flot library for graphic. But my image background in black. I use image/jpeg. I know that image/png will remove the background but I can't use it, because the another library must save this image to pdf. But she can use only jpeg. Thanks.

December 16, 2013 at 5:30 AM
srini vasan

while saving. file format is not on which i give...please help me to resolve

March 8, 2014 at 10:43 AM
Michael

If you want to change the file name you can do so by assigning it to the download tag.
Click Me!

However, if you want to change the file name but you don't have a link to add the download attribute to you can create a link using javascript and call the click function on it:
var a = document.createElement("a");
a.download = fileName + fileExtension;
a.href = strData;
a.click();

To use this code, change the contents of the function saveFile to that above. This is useful for automatically downloading multiple images. You may want to pass fileName and fileExtension as parameters to the saveFile function along with strData.

This worked for me on Windows 8.1, Chrome 33.0 although I did get the following warning message.
"This site is attempting to download multiple files. Do you want to allow this?"

March 26, 2014 at 8:43 AM
Post a Comment