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/

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/
Cool. Do you know if something similar is possible for SVG or VML?
April 9, 2008 at 12:54 AM CupBoy/ Fredrik
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 AnonymousOk. I guess you could technically/theoretically write an SVG parser & renderer that outputted base64 ;)
April 9, 2008 at 7:35 AM Mathieu 'p01' Henri/ Fredrik
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 );
April 9, 2008 at 8:50 AM AnonymousSeeing how much SVG implementors choke on the spec and get it wrong, you probably don't want to implement your own interpreter ;)
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.
April 9, 2008 at 10:53 AM antimatter15I'm sure there are better and nicer canvas paint applications out there.
If you combine this with http://fuchsia-design.com/CanvaSVG/, you effectively have a way to convert SVG to Canvas to Bitmap.
April 9, 2008 at 4:45 PM AnonymousExample: http://antimatter15.110mb.com/misc/svg2bitmap/index.xhtml
@anon: Grafio's Artist's Sketchbook is a nice Canvas based drawing widget.
April 10, 2008 at 12:57 AM mudIn 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 TjerkWWhat 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?
April 19, 2008 at 1:41 AM Breton SlivkaJust 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..
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 lorlarzSomeone 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 Sanchezso, can we save the canvas on a server directory (777)?
October 21, 2009 at 9:09 AM AnonymousHey,
March 9, 2010 at 1:26 PM Paul HayesI 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
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 DuttonIs there a way to get this to work with Chrome?
May 21, 2010 at 5:48 AM smokingunsI'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 GeorgeHas anyone tried posting the canvas image back to the server in a form?
May 24, 2010 at 3:54 PM smokinguns@Oliver George:
May 25, 2010 at 12:33 PM Sam DuttonIt'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);
Any joy with this?:
May 27, 2010 at 2:08 PM Alex>> 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. <<
is there any plan to make it work in chrome?
June 7, 2010 at 11:58 PM AnonymousI use it for converting a graph ( with flot - jquery plugin).
June 20, 2010 at 7:38 AM AnonymousI 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`?
Error: oScaledCanvas.toDataURL is not a function
July 1, 2010 at 1:05 PM AnonymousWhere is the toDataURL function defined. I keep getting this error and can't seem to crack it.
I also get the same error, tried opera 10.6 and ff 3.6.6, both with "PNG" and "JPEG"
July 15, 2010 at 11:00 AM AnonymousError: oScaledCanvas.toDataURL is not a function.
anyone has any clue ?
Hi !
August 15, 2010 at 11:59 PM AnonymousI 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 ?
FF 3.6.8 here as well and getting the toDataURL is not a function.
August 17, 2010 at 10:00 AM AnonymousDoesn'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?
Can you add the ability to specify the default filename in javascript when you save?
August 24, 2010 at 2:03 AM Hristo YankovI 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.
December 16, 2010 at 5:31 AM AnonymousIn 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().
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 AnonymousAny news about canvas behaviour and same-origin policy?
February 22, 2011 at 12:59 AM ValentinaDid someone find a work around ?
Is there a way to specify the filename of the image before saving it locally?
May 4, 2011 at 7:01 AM Bert PetersNice script, but please let it be noted that base64 libraries aren't needed.
July 8, 2011 at 12:17 PM MeysamSimply btoa and atob do just fine.
filename is always very long and contains random characters then .part
July 12, 2011 at 8:06 PM MithileshHello,
July 19, 2011 at 6:42 AM RohanbI 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 ??
hii..I want to save image on usb..How can i achieve this??
July 26, 2011 at 2:36 AM Overklogplease help
hi
September 20, 2011 at 3:05 PM Brigitte & Marc-André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?
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 GuinnipHas anyone had any luck saving a WebGL canvas using this library?
November 4, 2011 at 1:27 PM ruslanbcan I use it in a gwt app?
November 18, 2011 at 6:33 PM ldnessThe method doesn't seem to work on IE 9 (though most canvas-related operations I have used do). The statement
December 7, 2011 at 7:49 AM Bade.I.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.
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);"
March 28, 2012 at 6:51 AM Robbin PetterSimple as pie :)
hi,
April 13, 2012 at 7:33 AM FlaKaso 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
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 PedrasHi! I've been getting these "Security error" warnings on both Firefox and Chrome. Have any idea what this is about?
May 3, 2012 at 4:16 AM Tiago PedrasI was just doing a straight console.debug out of the canvas.toDataURL function
Hi! I've been getting these "Security error" warnings on both Firefox and Chrome. Have any idea what this is about?
May 3, 2012 at 4:16 AM NurI was just doing a straight console.debug out of the canvas.toDataURL function
amazing! thank you
May 3, 2012 at 8:06 AM Yaseen AbbasBlog design is an important aspect to attract visitors.
May 8, 2012 at 10:31 PM Jonas Ottenonline sweepstakes
church software
blackjack software
Hey there =)
June 25, 2012 at 3:58 AM Audrey ManiezHave 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?
Hello,
August 7, 2012 at 4:39 AM Jakob Kaltenbrunnerthanks for that, nearly what i was looking for.
Does a background image on the canvas can be rendered in the png file generated ?
http://greenethumb.com/article/1429/user-friendly-image-saving-from-the-canvas/
August 19, 2012 at 1:29 AM Jacques MulderThat's the solution for the filename and .part problem I was looking for, maybe others will also be looking for something like that
When i click on save. I get a .part file not a jpg or png on all three save buttons.
September 19, 2012 at 4:54 AM Jacques MulderFirefox 14
oh I see some has had the same problem already.
September 19, 2012 at 4:55 AM тупомеркаI'll check the link
I think, alpha channel saved with bugs for png format. (artefacts) Plaese check this version and correct.
October 2, 2012 at 3:07 AM MartinThx!
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 GoldingHi, please let me know how to initiate the download with JavaScript from canvas with a button as show in the example.
November 8, 2012 at 1:02 AM LiChenboThanks
Very appreciate yoru work, thanks.
November 12, 2012 at 10:36 AM Joey PadasianHi Jacob, really like this site, you've got some great knowledge here.
December 20, 2012 at 6:30 PM Farid GhaziI'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.
exception inside
March 30, 2013 at 5:33 PM Farid Ghaziat 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.
}
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 kevinI think you can now get it to use a filename in Chrome at least.
April 6, 2013 at 6:12 AM Waqar Haiderhttp://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download
Hello Everyone,
May 13, 2013 at 6:21 AM UnknownI 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
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