javascript - imagen - ArrayBuffer a la cadena codificada en base64
decodificar base64 javascript (9)
A continuación hay 2 funciones simples para convertir Uint8Array a Base64 String y viceversa
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
Necesito una forma eficiente (leer nativa) de convertir un ArrayBuffer en una cadena base64 que se debe usar en una publicación de varias partes.
Esto funciona bien para mi:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
En ES6, la sintaxis es un poco más simple:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Como se señala en los comentarios, este método puede dar como resultado un error de tiempo de ejecución en algunos navegadores cuando el ArrayBuffer es grande. El límite de tamaño exacto depende de la implementación en cualquier caso.
Hay otra forma asincrónica de usar Blob y FileReader.
No probé el rendimiento. Pero es una forma diferente de pensar.
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"
Mi recomendación para esto es NO utilizar estrategias de btoa
nativas, ya que no codifican correctamente todas las de ArrayBuffer
...
reescribe los DOMs atob () y btoa ()
Dado que DOMStrings son cadenas codificadas en 16 bits, en la mayoría de los navegadores que llaman a window.btoa en una cadena Unicode provocarán una excepción Character Out Of Range si un carácter excede el rango de un carácter codificado en ASCII de 8 bits.
Si bien nunca me he encontrado con este error exacto, he descubierto que muchos de los ArrayBuffer
que he intentado codificar tienen una codificación incorrecta.
Yo usaría la recomendación de MDN o bien.
Para aquellos a los que les gusta corto, aquí hay otro usando Array.reduce
que no causará desbordamiento de pila:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '''')
);
Puede derivar una matriz normal de ArrayBuffer
utilizando Array.prototype.slice
. Use una función como Array.prototype.map
para convertir bytes en caracteres y Array.prototype.map
para join
una cadena.
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
}
Este método es más rápido ya que no hay concatenaciones de cadenas ejecutándose en él.
Usé esto y funciona para mí.
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;
}
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 );
}
pero las implementaciones no nativas son más rápidas, por ejemplo, https://gist.github.com/958841 consulte http://jsperf.com/encoding-xhr-image-data/6
function _arrayBufferToBase64(uarr) {
var strings = [], chunksize = 0xffff;
var len = uarr.length;
for (var i = 0; i * chunksize < len; i++){
strings.push(String.fromCharCode.apply(null, uarr.subarray(i * chunksize, (i + 1) * chunksize)));
}
return strings.join("");
}
Esto es mejor si usa JSZip para descomprimir archivo de cadena