HTML5 / Javascript - DataURL转换为Blob & Blob转换为DataURL

66

我有一个来自展示我的网络摄像头的画布的DataURL。我使用Matt在这里的答案将此数据URL转换为blob:How to convert dataURL to file object in javascript?

如何将此blob重新转换回相同的DataURL?我花了一整天的时间研究这个问题,惊讶的是除非我瞎了,否则这并没有被更好地记录下来。

编辑:

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

但它只返回一个看起来指向本地文件的非常短的URL,但我需要通过网络发送网络摄像头数据。


1
或者如果有人知道任何其他两种在DataURL和Blob之间进行转换的方法,我将非常感激。这一直困扰着我。 - spacecoyote
1
能否将URL转换为Blob,通过网络发送Blob并再次将Blob转换为URL?我是否有思维错误? - spacecoyote
1
由于我尝试压缩DataURL字符串并以此方式发送它似乎也失败了,所以我将再次允许自己提出这个问题。 - spacecoyote
5个回答

113

使用我的代码在javascript中在数据URL和Blob对象之间进行转换(比您链接中的代码更好)。

//**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);
});

4
我认为对我来说不太明显的是,在调用readAsDataURL之前,需要添加onload事件到FileReader中。 - Jazzy

16

这是一个基于 Promise 的 Typescript 版本,具有适当的错误检查。

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);
  });
}

5

没事了,在遵循此线程中的说明并使我的服务器转发未经修改的原始二进制WebSocket帧后,它最终起作用了。

现在我仍在解决画布(<1fp)的性能问题,但这可能成为新主题的内容。


2

DataURL 转 Blob 有更好的解决方案:

const dataURL = "dataURL string...";
const res = await fetch(dataURL);
const blob = await res.blob();

简洁明了! - geogeo

1

我喜欢简洁明了的代码,所以这里提供一个基于 Promise 的一行代码来将 Blob 转换为 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);

或者,作为一个函数:
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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接