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 Jacob Seidelin/ 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 Anonymous/ 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 Jacob Seidelin@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 AnonymousI'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 Jacob Seidelin@mud: Thanks, I'll try and change that.
April 18, 2008 at 9:50 PM Tjerk WolterinkWhat 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 7Just 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 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 Unknown>> 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 HYI 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 Yours TrulyDid 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 MeisamSimply 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 Rooscan I use it in a gwt app?
November 18, 2011 at 6:33 PM AnonymousThe 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 jhonSimple 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 UnknownBlog design is an important aspect to attract visitors.
May 8, 2012 at 10:31 PM Unknownonline 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 Unknownthanks 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 UnknownThat'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 UnknownFirefox 14
oh I see some has had the same problem already.
September 19, 2012 at 4:55 AM AnonymousI'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 UnknownHi, 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 UnknownHi Jacob, really like this site, you've got some great knowledge here.
December 20, 2012 at 6:30 PM UnknownI'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 Unknownat 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 Anonymoushttp://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 AnonymousHello, 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)??
June 20, 2013 at 6:33 AM economy4allThank you very much.
The generated image is not copy/pastable to Word (though you can paste it in paint.net)
August 20, 2013 at 12:08 AM Milind MoreyDoes anyone have an idea how to make this image copy pastable to Word
good
December 3, 2013 at 6:05 AM UnknownThanks 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?
December 10, 2013 at 11:04 AM UnknownThanks, Ben
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 Unknownwhile saving. file format is not on which i give...please help me to resolve
March 8, 2014 at 10:43 AM AnonymousIf you want to change the file name you can do so by assigning it to the download tag.
March 26, 2014 at 8:43 AMClick 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?"