2012-02-13 20 views

答えて

142
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); 
} 

ですが、ネイティブではない実装はより高速です。

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

、構文は少し簡単です::https://gist.github.com/958841 はこれが私のために正常に動作http://jsperf.com/encoding-xhr-image-data/6

+4

リンクから非ネイティブの実装を試してみましたが、上記のループコードが1秒しかかからずに1Mサイズのバッファを変換するのに1分30秒かかりました。 – cshu

+0

私はこのアプローチの単純さが気に入っていますが、すべての文字列の連結はコストがかかることがあります。それは、文字の配列を構築するように見え、最後に 'join()'を実行すると、Firefox、IE、Safariでかなり速くなります(ただし、Chromeではかなり遅くなります):http://jsperf.com/tobase64-実装 – JLRishe

+0

配列バッファからbase64への変換にこの関数を使用していますが、配列バッファを取得できません。私は_base64ToArrayBuffer()関数をここでwrritenしている:http://codeshare.io/PT4pbしかし、それは私にエラーが表示されます: 'atob'を 'Window'で実行できませんでした:デコードする文字列が正しくエンコードされていません。 – bawejakunal

46

を参照してください、コメントで指摘したよう

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

、この方法は生じ得ますArrayBufferが大きい場合、一部のブラウザでランタイムエラーが発生する。正確なサイズ制限は、どの場合でも実装に依存します。

+26

私はこの方法が簡潔である方が好きですが、 "最大呼び出しスタックサイズ超過エラー"を取得します。上記のループ技法はそれを回避します。 – Jay

+11

私もスタックサイズのエラーを取得しているので、私はmobzの答えを使用し、それは素晴らしい仕事をした。 –

+0

これは簡潔に動作します、ありがとう – duckegg

-3
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(""); 
} 

これは、あなたが文字列

+0

何が間違っていますか? – RouR

+0

この関数は何をするのでしょうか?https://jsfiddle.net/as9t9ebf/ –

6

からアンパックアーカイブのJSZipを使用する場合は、このための私の推薦は、彼らがすべて正しくArrayBuffer年代をコードしないネイティブbtoaとしての戦略を、使用しないことです、良いです...

rewrite the DOMs atob() and btoa()

DOMStringsは、ほとんどのブラウザは、Unicode文字列にwindow.btoa呼び出しでCHARACの原因となります、16ビットでエンコードされた文字列であるので、 ter Out Of Range例外:文字が8ビットASCIIエンコード文字の範囲を超えています。

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

MDNの推奨または要点を使用します。

+0

'btoa'は文字列では動作しませんが、OPは' ArrayBuffer'を要求しています。 – tsh

+1

これは非常に多く、間違ったことを推薦する非常に多くのスニペットです!私はこのエラーを複数回見ました。そこでは人々が盲目的にatobとbtoaを使用します。 – Kugel

11

別の非同期の方法ブロブと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" 
6

私はこれを使用して私に役立ちます。

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; 
} 
+0

安全ではありません。@chemoishの回答 – Kugel

0

あなたは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 

} 

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

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

を参照してください。 @chemoishの回答 – Kugel

17

は、ここでスタックオーバーフローが発生することはありません Array.reduceを使用して、他の一つです
+0

を参照してくださいセクシーなダン! – Kano

1

以下は再び

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

base64StringToArray(s) { 
    let asciiString = atob(s); 
    return new Uint8Array([...asciiString].map(char => char.charCodeAt(0))); 
} 
をBase64でStringにUint8Arrayを変換するため2シンプルな機能のものがあります。それは短い好きな人のために
関連する問題