Save PNG Canvas Image to HTML5 Storage (JAVASCRIPT)?
Asked Answered
E

5

10

I am developing a chrome extension.

I open an image file in canvas, I apply some changes to it, then I am trying to save it to the HTML5 filesystem api.

First I get the dataURL from the canvas:

    var dataURL = canvas.toDataURL('image/png;base64'); 

Then just the data:

    var image64 = dataURL.replace(/data:image\/png;base64,/, '');

Then I make a Blob.

    var bb = new BlobBuilder();
    bb.append(image64);
    var blob = bb.getBlob('image/png');

Then I request the file system with the following function onInitFs();

    function onInitFs(fs) {
      fs.root.getFile('image.png', {create: true}, function(fileEntry) {
        // Create a FileWriter object for our FileEntry (log.txt).
        fileEntry.createWriter(function(fileWriter) {
        //WRITING THE BLOB TO FILE
        fileWriter.write(blob);
        }, errorHandler);
      }, errorHandler);
    }

    window.requestFileSystem(window.PERSISTENT, 5*1024*1024, onInitFs, errorHandler);

This results in a corrupted file being written to the file system.

I don't know what else I can do to make this work.

Could someone please guide me in the right direction.

The following are some of the sources to the functions I am using to accomplish this task.

http://dev.w3.org/html5/canvas-api/canvas-2d-api.html#todataurl-method

http://www.html5rocks.com/en/tutorials/file/filesystem/#toc-file-creatingempty

Thank You!

Epilepsy answered 21/6, 2011 at 20:0 Comment(2)
I don't like where HTML5 is going if people like you will randomly store 5MB of data on my hard disk...Undersize
It made that number big for testing purposes. I will definitely lower that number. I think that the plan for the future is that if an app is trying to use storage in your computer it will first ask for permission from the user to do so. But right now, you can specify "unlimitedStorage" in the manifest and you can store as much data as you want. :)Epilepsy
P
10

I've found a function that converts a data URL to a blob.

Great for when you need to save a canvas image to the sandboxed FileSystem. Works in Chrome 13.

function dataURItoBlob(dataURI, callback) {
    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs
    var byteString = atob(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]

    // write the bytes of the string to an ArrayBuffer
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    // write the ArrayBuffer to a blob, and you're done
    var bb = new window.WebKitBlobBuilder(); // or just BlobBuilder() if not using Chrome
    bb.append(ab);
    return bb.getBlob(mimeString);
};

Usage:

window.requestFileSystem(window.PERSISTENT, 1024*1024, function(fs){
    fs.root.getFile("image.png", {create:true}, function(fileEntry) {
        fileEntry.createWriter(function(fileWriter) {
            fileWriter.write(dataURItoBlob(myCanvas.toDataURL("image/png")));
        }, errorHandler);
    }, errorHandler);
}, errorHandler);

Source trail:

http://mustachified.com/master.js
via http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2011-April/031243.html
via https://bugs.webkit.org/show_bug.cgi?id=51652
via http://code.google.com/p/chromium/issues/detail?id=67587

Patin answered 15/8, 2011 at 23:34 Comment(3)
how can you read and display that image from the file system?Atrioventricular
@Atrioventricular <img src="filesystem:chrome-extension://YourExtensionID/persistent/image.png" />Patin
WebKitBlobBuffer and BlobBuilder are deprecatedWindbound
P
5

There is now a canvas.toBlob() polyfill: https://github.com/eligrey/canvas-toBlob.js
Other interesting link: https://github.com/eligrey/BlobBuilder.js

So with these it become easy to save image from canvas:

<script type="text/javascript" src="https://raw.github.com/eligrey/BlobBuilder.js/master/BlobBuilder.min.js"></script>
<script type="text/javascript" src="https://raw.github.com/eligrey/canvas-toBlob.js/master/canvas-toBlob.min.js"></script>
...
canvas.toBlob(function(blob) {
  fileWriter.write(blob);
}, "image/png");

Here is a little example using the FileSaver: http://jsfiddle.net/JR5XE/

Photophilous answered 30/1, 2012 at 19:26 Comment(0)
V
1

You seem to be directly writing the base64 representation to disk. You need to decode it first.

Vannoy answered 21/6, 2011 at 20:38 Comment(4)
Thank You! Is there a function out there that I can call to decode it?Epilepsy
Hi. I called the decode64() function I found here [ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html] on the image64 variable before creating my blob. This didn't work. Do I have to decode the blob or the image64 variable?Epilepsy
I also tried using the decoder from here: ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html But I did not get any results. Is this even possible?Epilepsy
encode decode base64 i done with two native functions atob() and btoa()... there are polyfills for browsers that dont support these.Underlay
M
1

I had been wondering the same thing and had a look at finding an answer.
From what I can tell you have to convert the raw string you get from an atob to an unit8array and then you can append it to a blob.
Here's an example that converts an image to a canvas and then the data from the canvas to a blob and then the third images src is set to the uri of the blob....you should be able to add the fs stuff from there....
http://jsfiddle.net/PAEz/XfDUS/
..sorry to not put the code here, but to be honest I couldnt figure out how to ;) and anyways, JSFiddle is a nice way to play with it.

References
https://gist.github.com/1032746
http://code.google.com/p/html5wow/source/browse/src/demos/photo-gallery/js/utils.js
Get image data in JavaScript?
http://jsdo.it/tsmallfield/typed_array

Menell answered 1/7, 2011 at 13:56 Comment(0)
C
0

You want HTMLCanvasElement.toBlob and then write the blob to a filesystem with the W3C filesystem API, but most browsers haven't implemented it yet.

Caterinacatering answered 13/7, 2011 at 0:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.