Die atob
Funktion entschlüsselt einen Base64-codierten String in einen neuen String mit einem Zeichen für jedes Byte der Binärdaten.
const byteCharacters = atob(b64Data);
Der Codepunkt (charCode) jedes Zeichens entspricht dem Wert des Bytes. Wir können ein Array von Byte-Werten erstellen, indem wir dies für jedes Zeichen im String mit der Methode .charCodeAt
anwenden.
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
Dieses Array von Byte-Werten kann in ein echtes Byten-Array umgewandelt werden, indem es dem Konstruktor Uint8Array
übergeben wird.
const byteArray = new Uint8Array(byteNumbers);
Dies wiederum kann in ein BLOB umgewandelt werden, indem es in ein Array eingewickelt und dem Konstruktor Blob
übergeben wird.
const blob = new Blob([byteArray], {type: contentType});
Der obige Code funktioniert. Die Leistung kann jedoch verbessert werden, indem die byteCharacters
in kleineren Slices verarbeitet werden, anstatt alles auf einmal zu verarbeiten. In meinen groben Tests scheinen 512 Bytes eine gute Slicegröße zu sein. Dies gibt uns die folgende Funktion.
const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
const blob = b64toBlob(b64Data, contentType);
const blobUrl = URL.createObjectURL(blob);
window.location = blobUrl;
Vollständiges Beispiel:
const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
const contentType = 'image/png';
const b64Data = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
const blob = b64toBlob(b64Data, contentType);
const blobUrl = URL.createObjectURL(blob);
const img = document.createElement('img');
img.src = blobUrl;
document.body.appendChild(img);