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.
.html#todataurl-method
Thank You!
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!
Share Improve this question asked Jun 21, 2011 at 20:00 RobRob 1011 gold badge1 silver badge3 bronze badges 2- I don't like where HTML5 is going if people like you will randomly store 5MB of data on my hard disk... – Blindy Commented Jun 21, 2011 at 20:05
- 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. :) – Rob Commented Jun 21, 2011 at 20:13
5 Answers
Reset to default 10I'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
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/
You seem to be directly writing the base64 representation to disk. You need to decode it first.
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
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.