web-dev-qa-db-ja.com

応答からのバイナリ画像をbase64文字列に解析する方法は?

REST APIからリクエストされた画像をbase64文字列に解析したい。

enter image description here

まず...この目的のためにwindow.btoa()関数を使用するだけで簡単だと思いました。

私のアプリケーションのそのような部分でそれをしようとすると:

_.done( function( response, position ) {
    var texture = new Image();
    texture.src = "data:image/png;base64," + window.btoa( response ); 
_

次のエラーが発生しました:Uncaught InvalidCharacterError:Failed to execute 'btoa' on 'Window':エンコードされる文字列にLatin1範囲外の文字が含まれています。

私がここで読んだように: javascript atobが 'Stringに無効な文字を含んでいます'

この問題は_newlines in the response_が原因で発生するため、window.btoa()が失敗しました。もちろん、任意のバイナリ画像形式には改行があります...しかし、上記のリンクから、提案はそれらの文字を削除/置換することでした-バイナリ画像からいくつかの文字を削除/置換する場合、破損しています。

もちろん、可能な代替案はAPIデザインに関連しています。-base64表現を返す関数を追加する-画像にURLを返す関数を追加する

修復しない場合、サーバーからbase64表現を返しますが、そのような方法は好きではありません。

上記のスクリーンショットの部分に示されているように、応答からのバイナリイメージの処理に関する問題を解決する方法はありますか?

21
user2402179

あなたが当たっている問題の一部は、jQuery.ajaxnot をサポートしていることです。バイナリデータをうまく処理できるXHR2 blob/arraybuffer型をネイティブにサポートしています( jQueryを使用したバイナリファイルの読み取り.ajax )。

xhr.responseType = 'arraybuffer'でネイティブXHRオブジェクトを使用し、応答配列を読み取り、それをBase64に変換すると、必要なものが得られます。

ここに私のために働く解決策があります:

// http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
function fetchBlob(uri, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', uri, true);
  xhr.responseType = 'arraybuffer';

  xhr.onload = function(e) {
    if (this.status == 200) {
      var blob = this.response;
      if (callback) {
        callback(blob);
      }
    }
  };
  xhr.send();
};

fetchBlob('https://i.imgur.com/uUGeiSFb.jpg', function(blob) {
  // Array buffer to Base64:
  var str = btoa(String.fromCharCode.apply(null, new Uint8Array(blob)));

  console.log(str);
  // Or: '<img src="data:image/jpeg;base64,' + str + '">'
});

https://jsfiddle.net/oy1pk8r3/2/

Base64でエンコードされたコンソール出力を生成します:/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAIBAQIBAQICAgICAgICAw.....

16
fotinakis

_arrayBufferToBase64()を使用してblobをループする代わりに、apply()を使用して変換を実行します。ブラウザでは30倍高速で、より簡潔です

// http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
function fetchBlob(uri, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', uri, true);
  xhr.responseType = 'arraybuffer';

  xhr.onload = function(e) {
    if (this.status == 200) {
      var blob = this.response;
      if (callback) {
        callback(blob);
      }
    }
  };
  xhr.send();
};

fetchBlob('https://i.imgur.com/uUGeiSFb.jpg', function(blob) {
  var str = String.fromCharCode.apply(null, new Uint8Array(blob));
  console.log(str);
  // the base64 data: image is then
  // '<img src="data:image/jpeg;base64,' + btoa(str) + '" />'     
});
5
rickdog

関数に渡す前に文字列でescapeを使用することを推測していますが、API呼び出しなしではテストできません。

テスト

encodeURI("testñ$☺PNW¢=")

戻り値

"test%C3%B1$%E2%98%BAPNW%C2%A2="

すべての文字をエスケープするだけで、文字列内のすべての不正な文字をエスケープする必要があります

テスト

encodeURI("¶!┼Æê‼_ðÄÄ┘Ì+\+,o▬MBc§yþó÷ö")

戻り値

"%C2%B6!%E2%94%BC%C3%86%C3%AA%E2%80%BC_%C3%B0%C3%84%C3%84%E2%94%98%C3%8C++,o%E2%96%ACMBc%C2%A7y%C3%BE%C3%B3%C3%B7%C3%B6"

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

1
FabianCook

発生している問題は、応答がUnicode文字列と見なされていることです。ここでUnicode文字列に関するセクションを参照してください: window.btoa

これでいくつかのソリューションが提供されます post

0
HungryBeagle