40
votes

I have a DataURL from a canvas that shows my webcam. I turn this dataURL into a blob using Matt's answer from here: How to convert dataURL to file object in javascript?

How do I convert this blob back into the same DataURL? I've spent a day researching this and I'm astouned this isn't documented better, unless I'm blind.

EDIT: There is

var urlCreator = window.URL || window.webkitURL; 
var imageUrl = urlCreator.createObjectURL(blob); 

but it only returns a really short URL that seems to point at a local file, but I need to send the webcam data over a network.

3
Or if someone knows of any other two methods to convert between DataURL and Blob, I'd be extremely grateful. It's nagging me. - spacecoyote
Is it even possible to turn a URL into a blob, send the blob over a network and turn the blob into a URL again? Do I have a thinking mistake? - spacecoyote
Since my attempts at compressing the dataURL string and sending it that way seem to be failing too, I'll allow myself to bump this once more. - spacecoyote

3 Answers

85
votes

Use my code to convert between dataURL and blob object in javascript. (better than the code in your link.)

//**dataURL to blob**
function dataURLtoBlob(dataurl) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
}

//**blob to dataURL**
function blobToDataURL(blob, callback) {
    var a = new FileReader();
    a.onload = function(e) {callback(e.target.result);}
    a.readAsDataURL(blob);
}

//test:
var blob = dataURLtoBlob('data:text/plain;base64,YWFhYWFhYQ==');
blobToDataURL(blob, function(dataurl){
    console.log(dataurl);
});
2
votes

Nevermind, it ended up working after sticking to the instructions in this thread Display image from blob using javascript and websockets and making my server forward raw (yet) unmodified BinaryWebSocketFrames.

Now I'm still fighting bad performance of the canvas (<1fp) but that might become subject of a new thread.

-1
votes

Here is a Promise-based Typescript version with proper error checking.

function blobToDataURL(blob: Blob): Promise<string> {
  return new Promise<string>((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = _e => resolve(reader.result as string);
    reader.onerror = _e => reject(reader.error);
    reader.onabort = _e => reject(new Error("Read aborted"));
    reader.readAsDataURL(blob);
  });
}