javascript - pgjvzhk - Usar datos de imágenes sin formato desde la solicitud ajax para URI de datos
data:image/jpeg;base64 (6)
Gracias por eso. He profundizado un poco más en esto y resulta que hay una solución al menos en las versiones actuales de Firefox y Chrome (EDIT: IE10 también funciona). Puede usar XMLHttpRequest2 y usar una matriz tipada (Uint8Array). El siguiente código funciona:
<!DOCTYPE html>
<html>
<head>
<script type=''text/javascript''>
function init()
{
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.open(''GET'',''/images/photos/badger.jpg'',true);
// Must include this line - specifies the response type we want
xmlHTTP.responseType = ''arraybuffer'';
xmlHTTP.onload = function(e)
{
var arr = new Uint8Array(this.response);
// Convert the int array to a binary string
// We have to use apply() as we are converting an *array*
// and String.fromCharCode() takes one or more single values, not
// an array.
var raw = String.fromCharCode.apply(null,arr);
// This works!!!
var b64=btoa(raw);
var dataURL="data:image/jpeg;base64,"+b64;
document.getElementById("image").src = dataURL;
};
xmlHTTP.send();
}
</script>
</head>
<body onload=''init()''>
<img id="image" alt="data url loaded image" />
</body>
</html>
Básicamente, solicita una respuesta binaria y luego crea una vista int sin firmar de 8 bits de los datos antes de convertirla de nuevo en una cadena (amigable con los binarios) String.fromCharCode (). La aplicación es necesaria ya que String.fromCharCode () no acepta un argumento de matriz. A continuación, usa btoa (), crea tu url de datos y luego funciona.
Los siguientes recursos fueron útiles para esto:
y
http://www.html5rocks.com/en/tutorials/file/xhr2/
Mella
Intento usar una combinación de AJAX y URI de datos para cargar una imagen JPEG y extraer sus datos EXIF con una sola solicitud HTTP. Estoy modificando una biblioteca ( https://github.com/kennydude/photosphere ) para hacer esto; Actualmente, esta biblioteca utiliza dos solicitudes HTTP para establecer la fuente de la imagen y obtener los datos EXIF.
Obtener el EXIF funciona, no hay problema. Sin embargo, tengo dificultades para usar los datos brutos de la solicitud de Ajax como fuente de la imagen.
Código fuente para una pequeña prueba de la técnica:
<!DOCTYPE html>
<html>
<head>
<script type=''text/javascript''>
function init()
{
// own ajax library - using it to request a test jpg image
new Ajax().sendRequest
(
"/images/photos/badger.jpg",
{ method : "GET",
callback: function(xmlHTTP)
{
var encoded = btoa (unescape(encodeURIComponent(xmlHTTP.responseText)));
var dataURL="data:image/jpeg;base64,"+encoded;
document.getElementById("image").src = dataURL;
}
}
);
}
</script>
<script type="text/javascript" src="http://www.free-map.org.uk/0.6/js/lib/Ajax.js"></script>
</head>
<body onload=''init()''>
<img id="image" alt="data url loaded image" />
</body>
</html>
Obtengo lo que parecen ser datos jpeg sensibles enviados de vuelta, y la longitud (en bytes) de los datos brutos y los datos brutos codificados en base64 y luego no codificados nuevamente son los mismos. Sin embargo, el intento de configurar la imagen src falla tanto en Firefox (25) como en Chrome (31) (versiones actuales): Chrome muestra el icono de "imagen rota", lo que sugiere que el src es un formato no válido.
Utilicé esta página de mozilla para obtener información sobre codificación / decodificación base64:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding
¿Alguna idea de lo que podría estar mal? Mirando a mi alrededor, puedo crear el lado del servidor de imágenes codificadas en base64, pero ¿se puede hacer del lado del cliente de esta manera? Por un lado, el lado del servidor de codificación base64 obviamente aumenta el tamaño de los datos y el propósito de este ejercicio es reducir la cantidad de datos que se transfieren del servidor, así como el número de solicitudes.
Gracias, Nick
He estado trabajando durante dos días en este tema, ya que necesitaba una solución para representar la Imagen del Perfil de Outlook del Usuario a partir de los datos brutos recibidos de Microsoft Graft. He implementado todas las soluciones anteriores, sin éxito. Luego encontré este git: obtengo los datos brutos base64 de la imagen de responseBody usando jquery ajax
En mi caso, acabo de reemplazar "data:image/png;base64,"
con "data:image/jpg;base64,"
Funciona a las mil maravillas.
La respuesta de Nick funciona muy bien. Pero cuando hice esto con un archivo bastante grande, obtuve un desbordamiento de pila en
var raw = String.fromCharCode.apply(null,arr);
Generar la cadena cruda en fragmentos funcionó bien para mí.
var raw = '''';
var i,j,subArray,chunk = 5000;
for (i=0,j=arr.length; i<j; i+=chunk) {
subArray = arr.subarray(i,i+chunk);
raw += String.fromCharCode.apply(null, subArray);
}
Tendrá que hacer la codificación base64 en el lado del servidor ya que responseText se trata como una Cadena, y los datos de respuesta que el servidor está enviando son binarios.
Tuve problemas con el ArrayBuffer -> String -> Base64
descrito anteriormente, pero me encontré con otro método que usa Blob que funcionó muy bien. No es una forma de convertir datos en bruto a Base 64 (como en el título), pero es una manera de mostrar datos de imágenes en bruto (como en la pregunta real):
var xhr = new XMLHttpRequest();
xhr.responseType = ''arraybuffer'';
xhr.onload = function() {
var blb = new Blob([xhr.response], {type: ''image/png''});
var url = (window.URL || window.webkitURL).createObjectURL(blb);
image.src = url;
}
xhr.open(''GET'', ''http://whatever.com/wherever'');
xhr.send();
Todo el mérito recae en Jan Miksovsky, autor de este violín . Me tropecé con eso y pensé que sería una adición útil a esta discusión.
Solución moderna basada en ES6 para la descarga de imágenes: (sin especificar el tipo de imagen)
async function downloadImageFromUrl(url) { // returns dataURL
const xmlHTTP = new XMLHttpRequest();
xmlHTTP.open(''GET'', url, true);
xmlHTTP.responseType = ''blob'';
const imageBlob = await new Promise((resolve, reject) => {
xmlHTTP.onload = e => xmlHTTP.status >= 200 && xmlHTTP.status < 300 ? resolve(xmlHTTP.response) : reject(Error(`wrong status: ${xmlHTTP.status}`));
xmlHTTP.onerror = reject;
xmlHTTP.send();
});
return blobToDataUrl(imageBlob);
}
function blobToDataUrl(blob) { return new Promise(resolve => {
const reader = new FileReader(); // https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
reader.onload = e => resolve(e.target.result);
reader.readAsDataURL(blob);
})}
Uso:
downloadImageFromUrl(''https://a.b/img.png'').then(console.log, console.error)