DataURL, Blob, and File are common front-end objects for storing binary data. They are used in different places and sometimes require conversions between the three
To DataURL
Blob ==> DataURL
The first and easiest way to parse a Blob object is to use FileReader:
const blob = new Blob([JSON.stringify({ hello: 'javascript' }, null.2)] and {type : 'application/json'});
const fr = new FileReader();
fr.onload = function (e) {
console.log(e.target.result); // data:application/json; base64,ewogICJoZWxsbyI6ICJqYXZhc2NyaXB0Igp9
}
fr.readAsDataURL(blob)
Copy the code
Of course, you can also choose to convert the Blob toa string and then use BTOA to convert it toa Base64-encoded DataURL
Note that bTOA requires primitive string encoding to be Latin-1. Latin-1 is a single-byte encoding character set, that is, each character encoding cannot exceed 255, otherwise an error will be reported
const blob = new Blob([JSON.stringify({ hello: 'javascript' }, null.2)] and {type : 'application/json'});
async function readAsDataURL(blob) {
const str = await blob.text();
const dataURL = 'data:' + blob.type + '; base64,' + btoa(str);
return dataURL;
}
readAsDataURL(blob).then(dataurl= > {
console.log(dataurl); // data:application/json; base64,ewogICJoZWxsbyI6ICJqYXZhc2NyaXB0Igp9
})
Copy the code
ArrayBuffer ==> DataURL
Similar to the Blob conversion to DataURL above, an ArrayBuffer can be converted to DataURL via BTOA
const arrBuf = await fetch('test.png').then(res= > res.arrayBuffer()); // Assume the data arrBuf is an ArrayBuffer
function readAsDataURL(arraybuffer, type) {
let str = ' ';
new Uint8Array(arraybuffer).forEach(code= > {
str += String.fromCodePoint(code);
});
return 'data:' + type + '; base64,' + btoa(str);
}
const dataURL = readAsDataURL(arrBuf, 'image/png');
Copy the code
Image ==> DataURL
If you want to convert images, there is another way to convert them indirectly via canvas:
One thing to note is that img needs to explicitly add img.crossOrigin = ‘Anonymous’, otherwise when canvas executes toDataURL(), toBlob(), getImageData(), it will throw an error due to cross-domain security:
Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
function imageToDataURL(imgurl) {
return new Promise((resolve, reject) = > {
const canvas = document.createElement('canvas');
const img = new Image();
img.src = imgurl;
img.crossOrigin = 'Anonymous';
img.onload = function() {
canvas.width = img.naturalWidth * window.devicePixelRatio;
canvas.height = img.naturalHeight * window.devicePixelRatio;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0.0, canvas.width, canvas.height);
const dataURL = canvas.toDataURL();
resolve(dataURL);
}
img.onerror = reject;
});
}
const dataURL = await imageToDataURL('http://test.com/image.png');
Copy the code
Into a Blob
DataURL ==> Blob
If your dataURL contains image data, you can also relay it via Canvas
function dataURLToBlob(dataurl) {
return new Promise((resolve, reject) = > {
const canvas = document.createElement('canvas');
const img = new Image();
img.src = dataurl;
img.crossOrigin = 'Anonymous';
img.onload = function() {
canvas.width = img.naturalWidth * window.devicePixelRatio;
canvas.height = img.naturalHeight * window.devicePixelRatio;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0.0, canvas.width, canvas.height);
canvas.toBlob(blob= > resolve(blob));
}
img.onerror = reject;
});
}
const blob = dataURLToBlob('data:image/png; base64,xxxxxxx');
Copy the code
The second method is to convert through the ATOB function
function dataURLToBlob(dataurl) {
const type = dataurl.match(/data:(.+); /) [1];
const base64 = dataurl.split(', ') [1];
const binStr = atob(base64);
const u8a = new Uint8Array(binStr.length);
let p = binStr.length;
while (p) {
p--;
u8a[p] = binStr.codePointAt(p);
}
return new Blob([u8a], { type });
}
ArrayBuffer==> Blob Blob objects can be built directly using arrayBufferconst blob = new Blob([arrayBuffer], { type: 'image/png' });
Copy the code
To ArrayBuffer
DataURL ==> ArrayBuffer
Just make a few changes to the way dataURL goes to BLOB
function dataURLToBlob(dataurl) {
const type = dataurl.match(/data:(.+); /) [1];
const base64 = dataurl.split(', ') [1];
const binStr = atob(base64);
const u8a = new Uint8Array(binStr.length);
let p = binStr.length;
while (p) {
p--;
u8a[p] = binStr.codePointAt(p);
}
return u8a.buffer;
}
Copy the code
Blob ==> ArrayBuffer
Blob objects have an arrayBuffer() method that can be converted directly. Note that this method returns a Promise object, and the value after resolve is an arrayBuffer
const blob = new Blob([1.2.3.4]);
const arrBuf = await blob.arrayBuffer();
Copy the code