Ich brauche eine effiziente (native Lese-) Methode, um einen ArrayBuffer in einen base64-String umzuwandeln, der in einem mehrteiligen Post verwendet werden muss.
function _arrayBufferToBase64( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
}
nicht-native Implementierungen sind jedoch schneller, z. https://Gist.github.com/958841 siehe http://jsperf.com/encoding-xhr-image-data/6
Das funktioniert gut für mich:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
In ES6 ist die Syntax etwas einfacher:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Wie in den Kommentaren darauf hingewiesen, kann diese Methode in einigen Browsern zu einem Laufzeitfehler führen, wenn der ArrayBuffer groß ist. Die genaue Größenbegrenzung ist in jedem Fall implementierungsabhängig.
Es gibt eine andere asynchrone Art, Blob und FileReader zu verwenden.
Ich habe die Leistung nicht getestet. Aber es ist eine andere Denkweise.
function arrayBufferToBase64( buffer, callback ) {
var blob = new Blob([buffer],{type:'application/octet-binary'});
var reader = new FileReader();
reader.onload = function(evt){
var dataurl = evt.target.result;
callback(dataurl.substr(dataurl.indexOf(',')+1));
};
reader.readAsDataURL(blob);
}
//example:
var buf = new Uint8Array([11,22,33]);
arrayBufferToBase64(buf, console.log.bind(console)); //"CxYh"
Für diejenigen, die es kurz mögen, hier ein anderer, der Array.reduce
verwendet, der keinen Stapelüberlauf verursacht:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
Meine Empfehlung hierfür ist, KEINE nativen btoa
-Strategien zu verwenden, da sie nicht alle ArrayBuffer
-Werte richtig codieren.
schreibe die DOMs atob () und btoa () um
Da DOMStrings 16-Bit-kodierte Zeichenfolgen sind, führt der Aufruf von window.btoa in einer Unicode-Zeichenfolge in den meisten Browsern zu einer Ausnahme außerhalb des Bereichs, wenn ein Zeichen den Bereich eines 8-Bit-ASCII-kodierten Zeichens überschreitet.
Obwohl ich diesen exakten Fehler noch nie gesehen habe, habe ich festgestellt, dass viele der ArrayBuffer
s, die ich versucht habe zu codieren, falsch codiert sind.
Ich würde entweder MDN-Empfehlung oder Gist verwenden.
Ich habe das benutzt und arbeitet für mich.
function arrayBufferToBase64( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
}
function base64ToArrayBuffer(base64) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array( len );
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
Nachfolgend finden Sie 2 einfache Funktionen zum Konvertieren von Uint8Array in Base64 String und zurück
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
Mit Array.prototype.slice
können Sie ein normales Array von der ArrayBuffer
ableiten. Verwenden Sie eine Funktion wie Array.prototype.map
, um Bytes in Zeichen umzuwandeln, und join
sie zusammen in eine Zeichenfolge.
function arrayBufferToBase64(ab){
var dView = new Uint8Array(ab); //Get a byte view
var arr = Array.prototype.slice.call(dView); //Create a normal array
var arr1 = arr.map(function(item){
return String.fromCharCode(item); //Convert
});
return window.btoa(arr1.join('')); //Form a string
}
Diese Methode ist schneller, da keine String-Verkettungen ausgeführt werden.
An meiner Seite musste ich mit Chrome Navigator DataView () verwenden, um einen arrayBuffer zu lesen
function _arrayBufferToBase64( tabU8A ) {
var binary = '';
let lecteur_de_donnees = new DataView(tabU8A);
var len = lecteur_de_donnees.byteLength;
var chaine = '';
var pos1;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( lecteur_de_donnees.getUint8( i ) );
}
chaine = window.btoa( binary )
return chaine;}