Come posso convertire l'immagine binaria dalla chiamata API all'URI di dati in JavaScript?
-
28-10-2019 - |
Domanda
L'API di Google che sto utilizzando sta trasmettendo le immagini solo come dati binari.
Non ho assolutamente idea di come metterlo in un URI di dati per visualizzarlo, grazie per qualsiasi aiuto!
La chiamata di cui sto parlando è Questa chiamata API.
Come puoi vedere, dice:
Il server restituisce byte della foto.
Per la chiamata (è un'estensione), utilizzo i metodi Chrome_EX_OAUTH. Forse ho bisogno di aggiungere qualcosa nell'intestazione per ottenere dati binari reali, non stringa in quanto arriva in questo momento ...
Quello che devo fare è convertire il binario risultante in URI di dati in modo da poterlo visualizzare.
Ok, lo esco dalla richiesta XHR
Ora, non conosco molto le cose binarie. Sono in qualche modo dati binari codificati che presumo? Ho provato a metterlo in BTOA e in altri coder di base64, tutto lancia un errore. Ho provato a sovrascriveremimeType con cose diverse e la "risposta" è cambiata in alcuni modi strani, ma nulla accetta i dati.
Quindi ora ho questo codice:
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');
Qualcun altro ha idea di come ottenere questo per me non comprensibile una risposta in un Uri di dati ???
Grazie per qualsiasi aiuto
Soluzione 2
Ok ho trovato la soluzione ...
Prima di tutto, la richiesta deve sovrascrivere il tipo di retrorazione in X-User definito
xhr.overrideMimeType('text\/plain; charset=x-user-defined');
Successivamente i dati non sono toccati dal browser.
Utilizzare il seguente encoder Base64
Base64 = {
// private property
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encodeBinary: function (input) {
var output = "";
var bytebuffer;
var encodedCharIndexes = new Array(4);
var inx = 0;
var paddingBytes = 0;
while (inx < input.length) {
// Fill byte buffer array
bytebuffer = new Array(3);
for (jnx = 0; jnx < bytebuffer.length; jnx++)
if (inx < input.length)
bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff; // throw away high-order byte, as documented at: https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data
else
bytebuffer[jnx] = 0;
// Get each encoded character, 6 bits at a time
// index 1: first 6 bits
encodedCharIndexes[0] = bytebuffer[0] >> 2;
// index 2: second 6 bits (2 least significant bits from input byte 1 + 4 most significant bits from byte 2)
encodedCharIndexes[1] = ((bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4);
// index 3: third 6 bits (4 least significant bits from input byte 2 + 2 most significant bits from byte 3)
encodedCharIndexes[2] = ((bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6);
// index 3: forth 6 bits (6 least significant bits from input byte 3)
encodedCharIndexes[3] = bytebuffer[2] & 0x3f;
// Determine whether padding happened, and adjust accordingly
paddingBytes = inx - (input.length - 1);
switch (paddingBytes) {
case 2:
// Set last 2 characters to padding char
encodedCharIndexes[3] = 64;
encodedCharIndexes[2] = 64;
break;
case 1:
// Set last character to padding char
encodedCharIndexes[3] = 64;
break;
default:
break; // No padding - proceed
}
// Now we will grab each appropriate character out of our keystring
// based on our index array and append it to the output string
for (jnx = 0; jnx < encodedCharIndexes.length; jnx++)
output += this._keyStr.charAt(encodedCharIndexes[jnx]);
}
return output;
}
};
C'è la roba magica pubblicata da Mozilla che non mi ha permesso di codificare correttamente le cose
bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff
Il codice finale sembrerebbe quindi questo ...
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');
});
PS Se si inserisce direttamente "Dati: Image/*" nella finestra del browser, scaricherà il file e non sarà in grado di aprirlo. Ma se lo metti direttamente in un IMG SRC funziona bene!
Altri suggerimenti
Dopo aver condotto alcuni test, ecco la mia risposta:
Per visualizzare semplicemente l'immagine usando il <img>
Tag, devi prima codificare il risultato binario con Base64. Puoi farlo in due modi diversi:
Usando JavaScript: Utilizzare una funzione encoder Base64, come questo. Dopo aver codificato i dati binari del risultato, è possibile visualizzare l'immagine utilizzando il
<img>
tag come così:<img src="data:image/*;base64,[BASE64 ENCODED BINARY]" />
. È necessario sostituire[BASE64 ENCODED BINARY]
con l'effettivo binario codificato dell'immagine. Suppongo che tu sappia già come modificare gli attributi elementi HTML tramite JavaScript, è abbastanza facile mettere il binario codificato nelsrc
attributo del<img>
etichetta.Usando PHP (la mia preferenza personale): Una volta inviata una richiesta GET all'API, ti restituirà il binario. Usa semplicemente il PHP
base64_encode()
funzione.<img src="data:image/*;base64,<?php echo base64_encode($result); ?>" />
Dove il $result
La variabile è ciò che ottieni dalla chiamata API. Puoi usare il Php Curl biblioteca.
Spero che questo aiuti.
Se stai usando un data:
Uri, prendo che non ti interessa i browser più vecchi. In tal caso, usa btoa()
come suggerito in Come puoi codificare una stringa su Base64 in JavaScript?, e ricadere l'alternativa menzionata nella seconda risposta. Poi il data:
Uri è semplice:
data:image/*;base64,<the btoa output>
Tutte le altre soluzioni sono obsolete. Non è necessaria alcuna base64. Guardare la mia risposta su Ottenere dati BLOB dalla richiesta XHR.