web-dev-qa-db-fra.com

Comment analyser en chaîne base64 l'image binaire de la réponse?

Je veux analyser l'image demandée de mon REST API dans la chaîne base64.

enter image description here

Tout d'abord ... J'ai pensé que ce serait facile, il suffit d'utiliser la fonction window.btoa() dans ce but.

Lorsque j'essaie de le faire dans une telle partie de ma demande:

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

J'ai l'erreur suivante: Uncaught InvalidCharacterError: échec de l'exécution de 'btoa' sur 'Window': la chaîne à encoder contient des caractères en dehors de la plage Latin1.

Comme je l'ai lu ici: atob javascript retournant 'La chaîne contient un caractère non valide'

Le problème se produit en raison de newlines in the response Et c'est pourquoi window.btoa() a échoué. Tout format d'image binaire aura bien sûr des retours à la ligne ... Mais à partir du lien ci-dessus, la suggestion était de supprimer/remplacer ces caractères - c'est une mauvaise suggestion pour moi, car si supprimer/remplacer certains caractères de l'image binaire, ce sera juste corrompu.

Bien sûr, les alternatives possibles concernent la conception de l'API: - pour ajouter une fonction, qui retourne une représentation base64 - pour ajouter une fonction, qui retourne l'url à l'image

Si je ne le répare pas, je retournerai la représentation base64 du serveur, mais je n'aime pas une telle façon.

Existe-t-il un moyen de résoudre mon problème avec la gestion de l'image binaire à partir de la réponse, comme indiqué ci-dessus dans la partie de la capture d'écran, n'est-ce pas?

21
user2402179

Je pense qu'une partie du problème que vous rencontrez est que jQuery.ajax ne pas prend en charge nativement les types d'objets blob/arraybuffer XHR2 qui peuvent très bien gérer les données binaires (voir Lecture de fichiers binaires à l'aide de jQuery.ajax ).

Si vous utilisez un objet XHR natif avec xhr.responseType = 'arraybuffer', puis lisez le tableau de réponses et convertissez-le en Base64, vous obtiendrez ce que vous voulez.

Voici une solution qui fonctionne pour moi:

// 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/

Produit une sortie de console encodée en base64: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAIBAQIBAQICAgICAgICAw.....

16
fotinakis

au lieu de parcourir le blob avec _arrayBufferToBase64 (), utilisez apply () pour effectuer la conversion, c'est 30 fois plus rapide dans mon navigateur et est plus concis

// 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

Je suppose d'utiliser escape sur la chaîne avant de la passer à la fonction, sans l'appel d'API, je ne peux pas me tester moi-même.

tester

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

retour

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

Il échappe juste à tous les caractères, il devrait échapper à tous les caractères illégaux de la chaîne

tester

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

retour

"%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

Le problème que vous rencontrez est que la réponse est considérée comme une chaîne Unicode. Voir la section sur les chaînes Unicode ici: window.btoa

Plusieurs solutions sont proposées dans ce post

0
HungryBeagle