web-dev-qa-db-ja.com

ArrayBufferからbase64エンコードされた文字列

ArrayBufferをマルチパート投稿で使用する必要があるbase64文字列に変換するための効率的な(ネイティブの読み取り)方法が必要です。

152
zaheer
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

178
mobz

これは私のためにうまくいきます:

var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));

ES6では、構文が少しシンプルになりました。

let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));

コメントで指摘されているように、このメソッドは、ArrayBufferが大きいときに一部のブラウザーで実行時エラーを引き起こす可能性があります。どんな場合でも、正確なサイズ制限は実装に依存します。

73
GOTO 0

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"
29
cuixiping

短くしたい人のために、スタックオーバーフローを引き起こさないArray.reduceを使用するもう1つの方法を次に示します。

var base64 = btoa(
  new Uint8Array(arrayBuffer)
    .reduce((data, byte) => data + String.fromCharCode(byte), '')
);
26
gkunz

これに対する私の推奨事項は、すべてのbtoaを正しくエンコードしないため、ネイティブのArrayBuffer戦略を使用しないことです…

DOM atob()およびbtoa()を書き換えます

DOMStringsは16ビットでエンコードされた文字列であるため、ほとんどのブラウザーでは、Unicodeストリングでwindow.btoaを呼び出すと、文字が8ビットASCIIエンコード文字の範囲を超える場合、Character Out Of Range例外が発生します。

この正確なエラーに遭遇したことはありませんが、エンコードしようとしたArrayBufferの多くが間違ってエンコードされていることがわかりました。

MDN推奨またはGistを使用します。

11
chemoish

私はこれを使用して、私のために働きます。

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;
}
9
Elias Vargas

以下は、Uint8ArrayをBase64 Stringに変換して戻すための2つの単純な関数です。

arrayToBase64String(a) {
    return btoa(String.fromCharCode(...a));
}

base64StringToArray(s) {
    let asciiString = atob(s);
    return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
4
Steve Dixon

Array.prototype.sliceを使用して、ArrayBufferから通常の配列を派生できます。 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

}

このメソッドは、文字列の連結が実行されていないため、高速です。

1
Charlie H

私の側では、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;}
0
Louvet Jean