So i have a canvas on which the user signs, now instead of converting it to a base 64 string i simply want to save it as an image itslef. whats the easiest way to do it html5??
-
This looks good: http://www.nihilogic.dk/labs/canvas2image/ – Billy Moon Aug 30 '12 at 17:28
2 Answers
You can easily do that this way (specifying the format as png in this case):
var img = canvas.toDataURL("image/png");
You can specify different image formats. Take a look at this answer.
-
thats exactly what i am saying, toDataURL converts it to a base64 encoded variable, is it not possible to create an image file directly – Black Mamba Aug 30 '12 at 11:06
-
You can save it in other image format as well, such as jpeg. And then use it in an html element. `document.write('
');` – rano Aug 30 '12 at 11:09
-
Yes that can be done, it will appear on my HTML page, my question/aim is somehow get a jpeg file and use it wherever i want – Black Mamba Aug 30 '12 at 11:18
-
You can upload it to a server of yours and then use it, or change its mime type and make it open in another window, so the browser does not recognize it and make it appear like a 'download' – rano Aug 30 '12 at 11:27
I've answered a similar question here:
Assuming you are saving locally
You can go the route of creating an image from a Data URL, but then saving it is the trickier part that currently isn't very nice using HTML5. It's hopefully going to get better soon, if browsers incorporate the download
attribute of the a tag
.
Obviously if you have higher permissions than a standard webpage... i.e. you are designing a browser plugin - then there are other options...
If I were to implement something like this myself, at the moment, I would conceed to using a flash plugin to handle the save to the local computer.
Assuming you are saving remotely
By the sounds of it you aren't saving to a server, but if so this is quite easy by just POSTing the base64 information to a script written in a server-side scripting language (i.e. like PHP) and getting that to write the data directly as binary to a file. Obviously you have to make certain you do this securely however, you don't want just any binary data written to your server's filesystem.
Best of both worlds
If you've got the development time, the best method to get a canvas image saved locally - without Flash - is to create a server-side script that instead of saving the data to your server actually writes the Base64 information you send it directly back as a realised binary image file. That way you can create a form that posts your Base64 data to a new tab, this request is evaluated by the server-side, and the binary image is returned... at which point the browser asks the user where they wish to save their image.
You'll need to define the correct headers to force an image to download (rather than display in-browser). A simple change to force this is to set the server-side script's Content-type
header to 'image/octect-stream'
... there are other header options to set which would be best researched (i.e. headers that control the filename and so forth).
reflect.php
<?php
/// a simple example..
if ( array_key_exists('data', $_POST) && ($data = $_POST['data']) ) {
header('Content-type: image/octet-stream');
echo base64_decode( $data );
exit;
}
and the form...
<form action="reflect.php" method="post" target="_blank">
<input name="data" type="hidden" value=" ... Base64 put here with JS ... ">
</form>
(The whole form should be created dynamically and submitted automatically with JavaScript)
Improving the user experience
There are ways to avoid a new tab being created, but you'd have to research to make sure these other methods don't cause cross-browser problems... for example you could post your form data as part of an iframe (which would keep the process hidden), or just post the data directly on the current window (..and hope that all the browsers receive the correct request and open a download rather than replace your page content - most modern browsers should handle this).
Improving security
With regards to a PHP script that automatically returns binary data, you should keep the access to this script secured by one time use key
/ authentication token
or something similar, and keep a limit on how much Base64 data you are willing to accept. It might not seem like it poses a secutiry risk - as you are not modifying your server in any way with what the user sends - but the dodgy people of this world could take your script and use it to send download request to other users... which if downloaded (and turned out to be unwanted trojans or viruses) would make your server implicit in providing the dodgy file.
All in all
Due to the effort required to get a simple thing like an image saved to the desktop, I wouldn't blame you for doing the following:
- Embed the image in the page (after taking your snapshot from canvas) and ask the user to right click and Save as...
Hopefully future things will make this situation better...
-
This last suggestion from pebbl is exactly what I said if you do not want to upload the file to a server of yours – rano Aug 30 '12 at 11:29
-
@rano - my last suggestion ('Best of both worlds' at time of writing) is not the same as what you've proposed... my first suggestion mentions the method you propose but states that it isn't quite good enough yet... considering when you action a data URL download from JavaScript there is no way to define the filename, & so on many different systems the file that is downloaded is useless to the average user. +1 for refering to the other post though as this has lots of useful mentions on it - including `Canvas2Image` which I had not heard of - unfortunately it still suffers the filename problem. – Pebbl Aug 30 '12 at 12:11
-
@pebble you're right 'exactly' is excessive, I was meaning that changing the mime type was the key to make the browser download it and not display it (as stated in one of my comments to my post) – rano Aug 30 '12 at 12:20