data - ¿Cómo puedo convertir el binario de imagen de la llamada de la API al URI de datos en Javascript?
image to data url (4)
La API de Google que estoy usando está transmitiendo imágenes solo como datos binarios.
Absolutamente no tengo idea de cómo poner esto en un URI de datos para mostrarlo, ¡gracias por cualquier ayuda!
La llamada de la que estoy hablando es esta llamada API .
Como puede ver, dice:
El servidor devuelve bytes de la foto.
Para la llamada (es una extensión), uso los métodos chrome_ex_oauth. Quizás necesite agregar algo en el encabezado para obtener datos binarios reales, no cadenas, ya que viene en este momento ...
Lo que tengo que hacer es convertir el binario resultante en URI de datos para que pueda mostrarlo.
Ok, obtengo esto de la solicitud de XHR
Ahora, no sé mucho de binario. Esto es, de alguna manera, datos binarios codificados, supongo? Traté de poner esto en btoa y otros codificadores base64, todo arroja un error. Traté de anularMimeType con diferentes cosas y la "respuesta" cambió de maneras extrañas, pero nada acepta los datos.
Entonces ahora tengo este código:
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'');
¿Alguien más tiene alguna idea de cómo obtener esto para mí no es una respuesta comprensible en un uri de datos?
Gracias por cualquier ayuda
Después de realizar algunas pruebas, esta es mi respuesta:
Para mostrar simplemente la imagen con la etiqueta <img>
, primero debe codificar el resultado binario con Base64. Puedes hacer esto de dos maneras diferentes:
Uso de Javascript: use una función de codificador Base64, como esta . Después de codificar los datos binarios de resultados, puede visualizar la imagen con la etiqueta
<img>
como:<img src="data:image/*;base64,[BASE64 ENCODED BINARY]" />
. Debe reemplazar[BASE64 ENCODED BINARY]
con el binario codificado real de la imagen. Supongo que ya sabes cómo cambiar los atributos del elemento HTML a través de Javascript, es bastante fácil poner el binario codificado en el atributosrc
de la etiqueta<img>
.Usando PHP (mi preferencia personal) : una vez que envíe una solicitud GET a la API, le devolverá el código binario. Simplemente use la función PHP
base64_encode()
.<img src="data:image/*;base64,<?php echo base64_encode($result); ?>" />
Donde, la variable $result
es lo que obtienes de la llamada API. Puede usar la biblioteca PHP cURL .
Espero que esto ayude.
Ok, encontré la solución ...
En primer lugar, la solicitud debe anular el tipo de returend en x-definido por el usuario
xhr.overrideMimeType(''text//plain; charset=x-user-defined'');
Después de eso, los datos no son tocados por el navegador.
Use el siguiente codificador 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;
}
};
Está el material mágico publicado por mozilla que no me permitió codificar las cosas correctamente
bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff
El código final se vería así ...
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'');
});
PD Si coloca "data: image / *" en la ventana del navegador directamente, descargará el archivo y no podrá abrirlo. ¡Pero si lo pones directamente en un img src, funciona bien!
Si está utilizando una data:
URI, entiendo que no le importan los navegadores más antiguos. En ese caso, use btoa()
como se sugiere en ¿Cómo se puede codificar una cadena a Base64 en JavaScript? , y recurra a la alternativa mencionada en la segunda respuesta . Entonces, los data:
URI es simple:
data:image/*;base64,<the btoa output>
Todas las otras soluciones son obsoletas. No se necesita Base64. Consulte mi respuesta sobre Cómo obtener datos BLOB de la solicitud XHR .