HTML5 / Javascript - DataURL to Blob & Blob to DataURL
Asked Answered
R

6

69

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.

Rucker answered 18/4, 2014 at 8:26 Comment(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.Rucker
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?Rucker
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.Rucker
R
5

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.

Rucker answered 18/4, 2014 at 13:46 Comment(0)
W
115

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);
});
Windgall answered 23/5, 2015 at 1:21 Comment(1)
I think the thing that was not obvious to me about FileReader is adding the onload event before you call readAsDataURLTigrinya
R
18

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);
  });
}
Reduplicative answered 15/5, 2021 at 21:0 Comment(0)
R
5

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.

Rucker answered 18/4, 2014 at 13:46 Comment(0)
F
2

DataURL to Blob has a better solution:

const dataURL = "dataURL string...";
const res = await fetch(dataURL);
const blob = await res.blob();
Fishmonger answered 19/11, 2022 at 17:22 Comment(1)
Nice and succint!Congreve
M
1

I like one-liners, so here's a Promise-based one to convert a blob to a data URL:

let blob = ...;
let dataUrl = await new Promise(r => {let a=new FileReader(); a.onload=r; a.readAsDataURL(blob)}).then(e => e.target.result);

Or, as a function:

function blobToDataUrl(blob) {
  return new Promise(r => {let a=new FileReader(); a.onload=r; a.readAsDataURL(blob)}).then(e => e.target.result);
}

let dataUrl = await blobToDataUrl(blob);
Mishap answered 13/4, 2022 at 16:17 Comment(0)
G
0

Angular

If using Angular it is possible to use Observables:

blobToDataURL(blob: Blob): Observable<string> {
    return new Observable((subscriber) => {
      const fr = new FileReader();
      fr.onload = () => {
        subscriber.next(fr.result as string);
        subscriber.complete();
      };
      fr.onerror = (error) => {
        subscriber.error(error);
      };
      fr.readAsDataURL(blob);
    })
  }
Granthem answered 11/4, 2024 at 17:24 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.