9
votes

Comment puis-je convertir une image binaire de l'appel de l'API en Uri de données en JavaScript?

L'API Google que j'utilise est de transmettre des images uniquement comme des données binaires.

Je n'ai absolument aucune idée de la procédure à suivre dans une URI de données pour l'afficher, merci pour toute aide! P>

L'appel dont je parle est Cet API appelle . P>

Comme vous pouvez le constater, il dit: P>

Le serveur renvoie des octets de la photo. P> BlockQuote>

Pour l'appel (c'est une extension), j'utilise les méthodes chromées_ex_oauth. Peut-être que j'ai besoin d'ajouter quelque chose dans l'en-tête pour obtenir de vraies données binaires, pas de la chaîne car elle vient en ce moment ... p>

Ce que je dois faire est de convertir le binaire résultant en uri de données afin que je puisse Affichez-le. p>


OK, je l'obtiens hors de la demande XHR p>

 Entrez la description de l'image ici P>

Maintenant, je ne connais pas beaucoup de choses binaires. Ceci est en quelque sorte codé des données binaires que je suppose? J'ai essayé de mettre cela dans BTOA et d'autres codeurs de base64, tout lancent une erreur. J'ai essayé de remplacer la nervation avec différentes choses et la "réponse" a changé de manière étrange, mais rien n'accepte les données. P>

alors j'ai donc ce code: p>

var nxhr = new XMLHttpRequest();
nxhr.onreadystatechange = function (data) {
    if (nxhr.readyState == 4) {
        console.log(nxhr);
    }
};
nxhr.open(method, url, true);
nxhr.setRequestHeader('GData-Version', '3.0');
nxhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
nxhr.send('Data to send');


6 commentaires

Binary ... des milliers [de] caractères laids ... vous savez que le binaire n'a que deux valeurs, correct?


Fileader? Cela ressemble à Java , pas JavaScript . Que diriez-vous de montrer un SSCCE ? Sinon, je n'ai vraiment aucune idée de ce que vous demandez.


@Joseph, peut-être qu'il déteste vraiment l'apparence de celles et des zéros.


HTML5 a FileReader ;-) Ouais Joseph, je sais :) Mais mettez des données binaires dans une chaîne, vous verrez plus de deux valeurs, non?


Lorsque vous placez binaire dans une chaîne, il affiche uniquement les caractères qu'il prend à partir d'une série de valeurs de caractères de 1 octet. Si vous stockez un entier de 4 octets quelque part et essayez de le lire via un tableau de 4 * 1 octet, vous obtiendrez 4 caractères différents. La représentation des chaînes est hors de propos, la séquence de bits est.


Ça jette une erreur? Quelle erreur? Quoi qu'il en soit, peut-être Essayez simplement de le lire comme binaire .


5 Réponses :


17
votes

Après avoir effectué des tests, voici ma réponse:

Pour afficher simplement l'image à l'aide de la balise , vous devez d'abord coder le résultat binaire avec base64. Vous pouvez le faire de deux manières différentes:

  1. Utilisation JavaScript: Utilisez une fonction de codeur de base64, telle que celle-ci . Après avoir encodé les données binaires de résultat, vous pouvez afficher l'image à l'aide de la balise comme: . Vous devez remplacer [binaire codé de base64] avec le binaire codé réel de l'image. Je suppose que vous savez déjà comment modifier les attributs d'élément HTML via JavaScript, il est assez facile de mettre le binaire codé dans l'attribut src de la balise . < / p>

  2. à l'aide de PHP (ma préférence personnelle) : Une fois que vous avez soumis une demande d'accès à l'API, cela vous retournera le binaire. Utilisez simplement la fonction PHP base64_encode () fonction.

    où, le résultat $ variable est ce que vous obtenez de l'appel de l'API. Vous pouvez utiliser le bibliothèque PHP Curl .

    J'espère que cela vous aidera.


10 commentaires

Merci, bien que j'ai déjà essayé un codeur de base64 (qui m'a dit une erreur "seulement peut gérer les codes ASCII") Je vais essayer de vous essayer. Comme je l'ai dit, c'est une extension (pour Chrome) où je ne peux accéder que via JS. De plus, je dois compter sur cette chromée_ex_oauth qui rend l'Ajax appelle pour moi. Pendant que je vais essayer votre solution, je voudrais vous demander de regarder l'OAuth, peut-être qu'il y a quelque chose qui rend les données retournées inutilisables pour mes besoins. code.google.com/chrome/extensions/tuut_oauth.html


Avez-vous ajouté la fonction de rappel pour le traitement de l'image? Sous "Envoyer des demandes d'API signées", l'exemple utilise obtenir avec une fonction de rappel. L'argument de sortie de cette fonction " resp " est la réponse de la réponse. Dans votre cas, il s'agit des données binaires. Puisque vous ne développez que pour chrome, utilisez la fonction BTOA () pour convertir ce binaire en base64 et l'ajouter à la fin de Data: image / *; base64, [base64 binaire] < / Code>, utilisez-le comme URI de l'image.


Je suis désolé de dire que cela ne fonctionne pas. Ni BTOA ni d'autres codeurs de base64 ne peuvent gérer ce qui vient à moi. J'ai essayé de remplacer la nervation sur l'objet XHR avec différents ensembles de caractères, j'ai essayé presque tout.


Ok, creusons plus profondément dans le code. Pouvez-vous me donner un extrait de votre code où vous faites la demande de prendre une photo? Si vous ne voulez pas l'afficher ici, vous pouvez l'envoyer à mon e-mail, dans mon profil.


De ce que je comprends, vous n'utilisez pas OAuth SendSigneDrequest méthode. La réponse XMLHTTPRÉQUESTPEQUEST QUE VOUS AVEZ ÊTRE CE QUE J'AVOIS CE QUE J'AVOIS. Disons que vous avez . Modifiez la source d'image avec document.getelementByID ("imagétag"). SRC = "Données: image / *; base64," + BTOA (NXHR.Response); .


Ouais, j'utilisais le XMLHTTPQUEST, car je peux définir des en-têtes, etc. Cela fonctionne comme dans SendSigneDrequest. Le problème est que la BTOA (NXHR.Response) jette une erreur ...


Erreur de BTOA (NXHR.RESPONSE): Invalid_Character_err: exception DOM 5


@Luke C'est pourquoi je n'aime pas JavaScript! :-P S'il vous plaît jeter un oeil à cette question et réponse: Stackoverflow.com/Questtions/8022425/... . Cela semble à la fin, vous faites la même chose :) laissez-moi savoir comment cela se passe.


Hey Ozbekov, j'ai trouvé une solution, regarde une réponse de la mienne. Merci quand même beaucoup pour votre aide! +1 !!!


Génial, pas de problème;) Je pourrais utiliser la prime si ça va :)



1
votes

Si vous utilisez un Data: URI, je le prends, vous ne vous souciez pas des navigateurs plus âgés. Dans ce cas, utilisez BTOA () suggéré dans Comment encoder une chaîne à base64 dans JavaScript? , et retomber sur L'alternative mentionnée dans la deuxième réponse . Ensuite, les données : URI est simple: xxx


8 commentaires

AFAIK, Internet Explorer prend en charge les données IMG depuis IE7. IE7 devrait être assez vieux assez vieux. En outre, BTOA () Les fonctions font partie de Gecko Dom et ne fonctionnent pas sur IE.


@Ozbekov: Ce n'est pas seulement gecko. Safari et Chrome le soutiennent aussi. Édité pour inclure ce que je voulais dire.


Mais c'est-à-dire que c'est exactement pourquoi j'ai fourni une fonction externe pour le codage.


@OZBEKOV: Et pourquoi j'ai édité ma réponse pour mentionner la deuxième réponse qui inclut une fonction alternative.


Hey les gars, ne vous inquiétez pas, simplement en utilisant Chrome, rien d'autre, ce sera une extension chromée. Hey, n'est-ce pas génial, de ne pas m'inquiéter à savoir? :)


L'asker de la question est à la recherche d'une méthode de conversion de données binaire (contenu d'image directement à partir d'une demande XHR) à la base64 codée. Le problème avec BTOA () est-ce pour une raison quelconque, il ne peut pas gérer les ensembles de caractères UTF-8. En fait, je suis ici parce que, de façon continue, BTOA () ne fonctionnera pas car il déclenche l'erreur: "Impossible d'exécuter" BTOA "sur" Fenêtre ": la chaîne à coder contient des caractères en dehors de la gamme Latin1. "


@chunk_split: UTF-8 n'entre pas en jeu ici (l'image n'est pas UTF-8, et non plus BTOA attendu UTF-8). Pour utiliser BTOA , vous avez besoin d'une chaîne issue de l'encodage des octets de l'image en tant que Latin-1 (par exemple, string.fromcharcode (... octets) d'un tableau d'octets à la place. du texte XHR). Ou du moins c'était la voie de 2011. De nos jours pour le codage de base64 En général, j'éviterais de passer à travers des chaînes binaires et d'utiliser un package qui fonctionne sur un uint8array (qui n'est inexplicablement pas intégré dans des navigateurs comme BTOA est).


@ Ry- ♦ comme il s'avère dans mon cas, je devais inclure xhr.overridemimeteype () pour empêcher le navigateur de modifier la réponse de sorte que BTOA () pourrait coder correctement une image de telle sorte qu'elle puisse être interprétée comme une URI de données. Voir ma réponse ci-dessous pour un peu plus de contexte. Mais vous avez raison, j'ai seulement supposé que c'était le coupable, quand en réalité, il devait quelque chose à faire avec la manipulation du type MIME dans le navigateur. Toujours pas certain ce qui se passe, cependant.



5
votes

OK J'ai trouvé la solution ...

Tout d'abord, la demande doit remplacer le type de rétention dans X-User défini h2> xxx pré>

après que les données est intacte par le navigateur. P>

Utilisez le codeur de base64 suivant H2>
oauth.authorize(function () {
    var method = "GET", params = {}, url = photo.href;

    var nxhr = new XMLHttpRequest();
    nxhr.onreadystatechange = function (data) {
        if (nxhr.readyState == 4) {
            console.log("<img src='data:image/*;base64," + Base64.encodeBinary(nxhr.response) + "' />");
        }
    };
    nxhr.open(method, url, true);
    nxhr.setRequestHeader('GData-Version', '3.0');
    nxhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
    nxhr.overrideMimeType('text\/plain; charset=x-user-defined'); 
});


2 commentaires

Je suis infructueux de faire fonctionner cette solution. Pourriez-vous fournir un violon de travail?


Bonjour @Luke pouvez-vous s'il vous plaît fournir le violon?



2
votes

Toutes les autres solutions sont obsolètes. Aucune base64 n'est nécessaire. Découvrez Ma réponse sur Obtenir des données BLOB de la demande XHR .


0 commentaires

1
votes

Je sais que c'est une très vieille question, mais comme cela se référait aux images et aux données binaires sur XHR, la sauce secrète pour moi est en deux étapes importantes:

Étape 1: strong> Assurez-vous d'utiliser un jeu de caractères défini sur l'utilisateur personnalisé pour empêcher le navigateur de modifier le contenu. par exemple p> xxx pré>

étape 2: strong> Utilisez string.fromcharcode (...) & 0XFF) code> à Désactivez le problème avec BTOA () CODE> Ne pas pouvoir gérer les chaînes binaires. Ceci a été inspiré par le gist @ https://gist.github.com/graylikeme/867848 (Et c'est actuellement noire magique pour moi en ce moment) Notez que, généralement, vous le feriez également parce que vous devez envoyer des en-têtes d'autorisation ou quelque chose aussi, mais cela n'est pas inclus dans cet exemple. P>

<div id="output-el"></div>
<script>
    var xhr = new XMLHttpRequest();
    xhr.addEventListener('readystatechange', function() {
        var outputEl = document.getElementById('xhr-output');

        // Done?
        if (this.readyState === 4) {

            // Make sure this is an image.
            var contentType = this.getResponseHeader('content-type');
            if (contentType !== null && contentType.indexOf('image/') === 0) {
                // Prepare binary response so we can base64 encode it (and btoa() function doesn't freak out).
                // Thanks to: https://gist.github.com/graylikeme/867848
                var response = this.responseText;
                var binary = '';
                for(i=0; i < response.length; i++) {
                    binary += String.fromCharCode(response.charCodeAt(i) & 0xff);
                }

                // Drop into data URI.
                var encoded = btoa(binary);
                outputEl.innerHTML = `<img alt="image preview" src="data:${contentType};base64,${encoded}">`;

            } else {
                console.log('Got a non-image response:', this.responseText);
            }
        }
    });

    // Make sure browser doesn't alter the response before we handle it.
    xhr.overrideMimeType('text\/plain; charset=x-user-defined');
    xhr.open('GET', 'https://example.com/path/to/some/image.jpg');
    xhr.send();
</script>


0 commentaires