Las fotos de la cámara digital a menudo se guardan como JPEG con una etiqueta de "orientación" EXIF. Para que se muestren correctamente, las imágenes deben girarse / reflejarse según la orientación establecida, pero los navegadores ignoran esta información que representa la imagen. Incluso en grandes aplicaciones web comerciales, el soporte para la orientación EXIF puede ser irregular 1 . La misma fuente también proporciona un buen resumen de las 8 orientaciones diferentes que puede tener un JPEG:
Las imágenes de muestra están disponibles en 4 .
La pregunta es cómo rotar / reflejar la imagen en el lado del cliente para que se muestre correctamente y pueda procesarse si es necesario.
Hay bibliotecas JS disponibles para analizar datos EXIF, incluido el atributo de orientación 2 . Flickr observó un posible problema de rendimiento al analizar imágenes grandes, que requieren el uso de trabajadores web 3 .
Las herramientas de la consola pueden reorientar correctamente las imágenes 5 . Un script PHP para resolver el problema está disponible en 6
fuente
canvas.toDataURL()
y decodificar y guardarlo en el lado del servidor.<img>
etiqueta normal ?La transformación de contexto de Mederr funciona perfectamente. Si necesita extraer la orientación, use esta función ; no necesita ninguna biblioteca de lectura EXIF. A continuación se muestra una función para restablecer la orientación en la imagen base64. Aquí hay un violín para ello . También he preparado un violín con demostración de extracción de orientación .
fuente
switch
no es necesario, ya que esa transformación no hace nada. Además, considere usar ensrcOrientation > 4 && srcOrientation < 9
lugar de[5,6,7,8].indexOf(srcOrientation) > -1
, porque es más rápido y requiere menos recursos (tanto RAM como CPU). No hay necesidad de tener una matriz allí. Esto es importante cuando se agrupan muchas imágenes, donde cada bit cuenta. De lo contrario, muy buena respuesta. ¡Votado!indexOf
ser comparado con lo que propusiste. Ejecuté un bucle simple con 10M de iteraciones y fue 1400% más rápido. Niza: D ¡Muchas gracias!getOrientation
, tengo curiosidad por saber si esto es eficiente en términos de rendimiento.getOrientation
llamadasfileReader.readAsArrayBuffer
, y luego llamamosURL.createObjectURL
y pasamos el resultado aresetOrientation
, que carga esta URL como una imagen. ¿Significa esto que el archivo de imagen será "cargado" / leído por el navegador no una sino dos veces, o no lo entiendo?image-orientation: from-image
cuando se usa.Si
Luego puede usar estas transformaciones para convertir la imagen en orientación 1
De orientación:
ctx.transform(1, 0, 0, 1, 0, 0);
ctx.transform(-1, 0, 0, 1, width, 0);
ctx.transform(-1, 0, 0, -1, width, height);
ctx.transform(1, 0, 0, -1, 0, height);
ctx.transform(0, 1, 1, 0, 0, 0);
ctx.transform(0, 1, -1, 0, height, 0);
ctx.transform(0, -1, -1, 0, height, width);
ctx.transform(0, -1, 1, 0, 0, width);
Antes de dibujar la imagen en ctx
fuente
ok, además de la respuesta @ user3096626, creo que será más útil si alguien proporciona un ejemplo de código, el siguiente ejemplo le mostrará cómo corregir la orientación de la imagen que proviene de la URL (imágenes remotas):
Solución 1: usar javascript (recomendado)
debido a que la biblioteca de imágenes de carga no extrae etiquetas exif solo de imágenes de URL (archivo / blob), usaremos las bibliotecas javascript de exif-js y de carga de imágenes , así que primero agregue estas bibliotecas a su página de la siguiente manera:
Tenga en cuenta que la versión 2.2 de exif-js parece tener problemas, por lo que utilizamos 2.1
entonces básicamente lo que haremos es
a - carga la imagen usando
window.loadImage()
b - lee las etiquetas exif usando
window.EXIF.getData()
c - convierta la imagen a lienzo y arregle la orientación de la imagen usando
window.loadImage.scale()
d - coloca el lienzo en el documento
aqui tienes :)
por supuesto, también puede obtener la imagen como base64 del objeto de lienzo y colocarla en el atributo img src, por lo que puede usar jQuery;)
Aquí está el código completo en: github: https://github.com/digital-flowers/loadimage-exif-example
Solución 2: usando html (pirateo del navegador)
hay un hack muy rápido y fácil, la mayoría de los navegadores muestran la imagen en la orientación correcta si la imagen se abre dentro de una nueva pestaña directamente sin ningún html (LOL, no sé por qué), así que básicamente puedes mostrar tu imagen usando iframe poniendo el atributo iframe src como la url de la imagen directamente:
Solución 3: usando CSS (solo Firefox y Safari en iOS)
hay un atributo css3 para corregir la orientación de la imagen, pero el problema es que solo funciona en firefox y safari / ios, todavía vale la pena mencionarlo porque pronto estará disponible para todos los navegadores (información de soporte del navegador de caniuse )
fuente
Para aquellos que tienen un archivo de un control de entrada, no saben cuál es su orientación, son un poco vagos y no quieren incluir una gran biblioteca a continuación, el código proporcionado por @WunderBart se combina con la respuesta a la que se vincula ( https://stackoverflow.com/a/32490603 ) que encuentra la orientación.
que fácilmente se puede llamar así
fuente
image/jpeg
lugar del predeterminadoimage/png
y cambiar el tamaño de la imagen de salida a un ancho máximo (400 px en mi caso) hizo una gran diferencia. (esto funciona bien para las miniaturas, pero si tiene que mostrar la imagen completa, sugiero evitar base64 y simplemente inyectar el elemento de lienzo directamente en la página ...)La respuesta de WunderBart fue la mejor para mí. Tenga en cuenta que puede acelerarlo mucho si sus imágenes son a menudo correctas, simplemente probando primero la orientación y omitiendo el resto del código si no se requiere rotación.
Poniendo toda la información de wunderbart juntos, algo como esto;
fuente
-2
y-1
regresar desdegetOrientation
para no intentar rotar imágenes que no sean jpgs o sin datos de rotación.file.slice()
optimización también, pero el impulso real proviene del uso de imágenes yimage/jpeg
formatos de salida más pequeños para crear URL de datos más pequeños. (no hay un retraso notable incluso para imágenes de 10 megapíxeles.)file.slice()
, ya que evitará la compatibilidad con las fuentes de imagen base64.Un trazador de líneas alguien?
No he visto a nadie mencionar la
browser-image-compression
biblioteca . Tiene una función auxiliar perfecta para esto.Uso:
const orientation = await imageCompression.getExifOrientation(file)
Una herramienta tan útil en muchas otras formas también.
fuente
File
objetos hasta donde yo sé. Lo mejor sería enviar la imagen y la orientación al servidor y manipular los archivos allí. O podría generar una cadena base64 usandocanvas
y eltoDataURL
método.Creé una clase envuelta en un módulo ES6 que resuelve exactamente esto.
Son 103 líneas, sin dependencias, y bastante bien estructuradas y documentadas, destinadas a ser fáciles de modificar / reutilizar.
Maneja las 8 orientaciones posibles y está basado en promesas.
Aquí tienes, espero que esto ayude a alguien: https://gist.github.com/vdavid/3f9b66b60f52204317a4cc0e77097913
fuente
Estoy usando una solución mixta (php + css).
Se necesitan contenedores para:
div.imgCont2
contenedor necesario para rotar;div.imgCont1
contenedor necesario para zoomOut -width:150%
;div.imgCont
contenedor necesario para barras de desplazamiento, cuando la imagen es zoomOut..
fuente
Además de la respuesta de @fareed namrouti,
Esto debe usarse si la imagen tiene que ser explorada desde un elemento de entrada de archivo
fuente
He escrito un pequeño script php que rota la imagen. Asegúrese de almacenar la imagen a favor de volver a calcularla en cada solicitud.
Salud
fuente