ArrayBuffer для base64 кодированной строки
Мне нужен эффективный (для чтения на родном) способ конвертировать ArrayBuffer в строку base64, которую нужно использовать в составном посте.
20 ответов
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 );
}
но не родные реализации быстрее, например https://gist.github.com/958841 см. http://jsperf.com/encoding-xhr-image-data/6
Это прекрасно работает для меня:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
В ES6 синтаксис немного проще:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Как указано в комментариях, этот метод может привести к ошибке во время выполнения в некоторых браузерах, когда ArrayBuffer большой. Точное ограничение размера зависит от реализации в любом случае.
Для тех, кто любит это коротко, вот другой, использующий Array.reduce
что не приведет к переполнению стека:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
В OP не указана среда выполнения, но если вы используете Node.JS, есть очень простой способ сделать это.
В соответствии с официальными документами Node.JS https://nodejs.org/api/buffer.html
// This step is only necessary if you don't already have a Buffer Object
const buffer = Buffer.from(yourArrayBuffer);
const base64String = buffer.toString('base64');
Кроме того, если вы работаете, например, под Angular, класс Buffer также будет доступен в среде браузера.
Есть еще один асинхронный способ использования Blob и FileReader.
Я не проверял производительность. Но это другой способ мышления.
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"
var blob = new Blob([arrayBuffer])
var reader = new FileReader();
reader.onload = function(event){
var base64 = event.target.result
};
reader.readAsDataURL(blob);
Я использовал это и работает для меня.
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;
}
Моя рекомендация для этого не использовать родной btoa
стратегии - так как они не правильно кодируют все ArrayBuffer
"S...
переписать DOMs atob() и btoa()
Поскольку строки DOMString представляют собой строки с 16-битным кодированием, в большинстве браузеров вызов окна window.btoa для строки Unicode вызовет исключение "Символ вне диапазона", если символ превышает диапазон 8-битного символа в кодировке ASCII.
Хотя я никогда не сталкивался с этой точной ошибкой, я обнаружил, что многие из ArrayBuffer
Я пытался закодировать неправильно.
Я бы либо использовал рекомендацию MDN, либо суть.
Ниже приведены две простые функции для преобразования Uint8Array в Base64 String и обратно
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
Это сработало для меня:
Buffer.from(myArrayBuffer).toString("base64");
Если у вас все в порядке с добавлением библиотеки, base64-arraybuffer:
yarn add base64-arraybuffer
тогда:
-
encode(buffer)
- Кодирует ArrayBuffer в строку base64 -
decode(str)
- Декодирует строку base64 в ArrayBuffer
Вы можете получить нормальный массив из ArrayBuffer
используя Array.prototype.slice
, Используйте функцию как Array.prototype.map
преобразовать байты в символы и join
они вместе в форматную строку.
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
}
Этот метод работает быстрее, так как в нем нет конкатенации строк.
я используюTextDecode
api, чтобы преобразовать его в обычный текст, а затем преобразовать в Base64.
const uint = new Uint8Array([ 73, 32, 108, 111, 118, 101, 32, 121, 111, 117 ]).buffer
const decoder = new TextDecoder()
const decodedText = decoder.decode(uint)
const base64Code = btoa(decodedText)
Я опаздываю на вечеринку, но этот родной и довольно короткий.
const blob = new Blob( [ your-fancy-buffer ], { type: "image/jpeg" } );
const urlCreator = window.URL || window.webkitURL;
base64string = urlCreator.createObjectURL(blob)
ABtoB64(ab) {
return new Promise(res => {
const fr = new FileReader();
fr.onload = ({target: {result: s}}) => res(s.slice(s.indexOf(';base64,') + 8));
fr.readAsDataURL(new Blob([ab]));
});
}
асинхронный метод с использованием программы чтения файлов.
В браузере предложены решения сbtoa
кажутся прекрасными. Но в Node.js btoa устарела.
Рекомендуется использоватьbuffer.toString(encoding)
нравиться
const myString = buffer.toString("base64")
var uint8Array = new Uint8Array(BytesArray);
var base64Str = btoa(String.fromCharCode(...uint8Array));
Or,
var base64Str = btoa(uint8Array.reduce((x, y) => x + String.fromCharCode(y), ''));
Использовать uint8-to-b64
пакет для кодирования / декодирования в браузере и Node.js
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("");
}
Это лучше, если вы используете JSZip для распаковки архива из строки
Со своей стороны, используя навигатор Chrome, мне пришлось использовать DataView() для чтения arrayBuffer
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;}