Durante las últimas semanas he estado trabajando con imágenes en objetivo-c y he notado muchos comportamientos extraños. Primero, como muchas otras personas, he tenido este problema en el que las imágenes tomadas con la cámara (o tomadas con la cámara de otra persona y MMS enviadas a mí) se rotan 90 grados. No estaba seguro de por qué en el mundo estaba sucediendo esto (de ahí mi pregunta ), pero pude encontrar una solución barata.
Mi pregunta esta vez es ¿por qué está sucediendo esto ? ¿Por qué Apple rota las imágenes? Cuando tomo una foto con mi cámara hacia arriba, a menos que realice mi código mencionado anteriormente, cuando guardo la foto, se guarda rotada. Ahora, mi solución estaba bien hasta hace unos días.
Mi aplicación modifica píxeles individuales de una imagen, específicamente el canal alfa de un PNG (por lo que cualquier conversión de JPEG se descarta de la ventana para mi escenario). Hace unos días noté que aunque la imagen se muestra correctamente en mi aplicación gracias a mi código de solución, cuando mi algoritmo modifica los píxeles individuales de la imagen, cree que la imagen está rotada. Entonces, en lugar de modificar los píxeles en la parte superior de la imagen, modifica los píxeles en el costado de la imagen (¡porque cree que debería rotarse)! No puedo entender cómo rotar la imagen en la memoria; idealmente, preferiría borrar esa imageOrientation
bandera por completo.
Aquí hay algo más que también me ha desconcertado ... Cuando tomo la foto, el imageOrientation
está configurado en 3. Mi código de solución es lo suficientemente inteligente como para darse cuenta de esto y darle la vuelta para que el usuario nunca se dé cuenta. Además, mi código para guardar la imagen en la biblioteca se da cuenta de esto, la voltea y luego la guarda para que aparezca correctamente en el rollo de la cámara.
Ese código se ve así:
NSData* pngdata = UIImagePNGRepresentation (self.workingImage); //PNG wrap
UIImage* img = [self rotateImageAppropriately:[UIImage imageWithData:pngdata]];
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
Cuando cargo esta imagen recién guardada en mi aplicación, el imageOrientation
es 0, exactamente lo que quiero ver, y mi solución alternativa de rotación ni siquiera necesita ejecutarse (nota: al cargar imágenes de Internet en lugar de imágenes tomadas con una cámara , el imageOrientation
es siempre 0, lo que resulta en un comportamiento perfecto). Por alguna razón, mi código de guardado parece borrar esta imageOrientation
bandera. Esperaba robar ese código y usarlo para borrar mi orientación de imagen tan pronto como el usuario toma una foto y la agrega a la aplicación, pero no parece funcionar. ¿Hace UIImageWriteToSavedPhotosAlbum
algo especial con imageOrientation
?
¿La mejor solución para este problema sería simplemente desaparecer imageOrientation
tan pronto como el usuario haya terminado de tomar una imagen? Supongo que Apple ha realizado el comportamiento de rotación por una razón, ¿verdad? Algunas personas sugirieron que se trata de un defecto de Apple.
(... si aún no estás perdido ... Nota 2: cuando tomo una foto horizontal, todo parece funcionar perfectamente, como las fotos tomadas de Internet)
EDITAR:
Así es como se ven realmente algunas de las imágenes y escenarios. Según los comentarios hasta ahora, parece que este comportamiento extraño es más que un comportamiento de iPhone, que creo que es bueno.
Esta es una imagen de la foto que tomé con mi teléfono (tenga en cuenta la orientación correcta), aparece exactamente como estaba en mi teléfono cuando tomé la foto:
Así es como se ve la imagen en Gmail después de enviármela por correo electrónico (parece que Gmail la maneja correctamente):
Así es como se ve la imagen como miniatura en Windows (no parece que se maneje correctamente):
Y así es como se ve la imagen real cuando se abre con el Visor de fotos de Windows (aún no se maneja correctamente):
Después de todos los comentarios sobre esta pregunta, esto es lo que estoy pensando ... El iPhone toma una imagen y dice "para mostrarla correctamente, es necesario girarla 90 grados". Esta información estaría en los datos EXIF. (No sé por qué es necesario rotarlo 90 grados, en lugar de tomar la vertical recta por defecto). A partir de aquí, Gmail es lo suficientemente inteligente como para leer y analizar esos datos EXIF y mostrarlos correctamente. Sin embargo, Windows no es lo suficientemente inteligente para leer los datos EXIF y, por lo tanto, muestra la imagen incorrecta . ¿Son correctas mis suposiciones?
fuente
Respuestas:
Hice I + D y descubrí que cada archivo de imagen tiene propiedades de metadatos. Si los metadatos especifican la orientación de la imagen, la cual generalmente es ignorada por otros sistemas operativos excepto Mac. La mayoría de las imágenes tomadas tienen sus propiedades de metadatos configuradas en ángulo recto. Entonces Mac lo muestra de manera girada 90 grados. Puede ver la misma imagen de forma adecuada en el sistema operativo Windows.
Para obtener más detalles, lea esta respuesta http://graphicssoft.about.com/od/digitalphotography/f/sideways-pictures.htm
intente leer el exif de su imagen aquí http://www.exifviewer.org/ , o http://regex.info/exif.cgi , o http://www.addictivetips.com/internet-tips/view-complete-exif -información-de-metadatos-de-cualquier-imagen-jpeg-online /
fuente
Tuve el mismo problema cuando obtuve la imagen de Camera, puse el siguiente código para solucionarlo .. Agregué el método scaleAndRotateImage desde aquí
fuente
Copiar / pegar rápidamente Traducción rápida de la excelente respuesta de Dilip .
fuente
La respuesta a esto es muy simple. Apple NO está rotando la imagen. Ahí es donde radica la confusión.
La cámara CCD no gira, por lo que siempre toma la foto en modo horizontal.
Apple hizo algo muy inteligente, en lugar de gastar todo el tiempo para rotar la imagen, barajando megabytes de datos, simplemente etiquételo con CÓMO se tomó la foto.
OpenGL realiza traducciones muy fácilmente, por lo que los DATOS nunca se mezclan, solo CÓMO SE DIBUJAN.
De ahí los metadatos de orientación.
Esto se convierte en un problema si desea recortar, cambiar el tamaño, etc., pero una vez que sepa lo que está sucediendo, simplemente defina su matriz y todo funcionará.
fuente
Versión Swift 4 con comprobaciones de seguridad de la respuesta de Dilip .
fuente
(bounds.size.height, bounds.size.width) = (bounds.size.width, bounds.size.height)
prescindir de crear una variable como almacenamiento.bounds.size.height.round()
bounds.size.width.round()
Cualquier imagen generada por iPhone / iPad se guarda como Horizontal Left con etiqueta EXIF Orientation (Exif.Image.Orientation) que especifica la orientación real.
Tiene los siguientes valores: 1: horizontal a la izquierda 6: vertical normal 3: horizontal a la derecha 4: vertical al revés
En IOS, la información EXIF se lee correctamente y las imágenes se muestran de la misma forma en que se tomaron. Pero en Windows, NO se usa la información EXIF.
Si abre una de estas imágenes en GIMP, dirá que la imagen tiene información de rotación.
fuente
Para cualquier otra persona que use Xamarin, aquí hay una traducción en C # de la excelente respuesta de Dilip y un agradecimiento a thattyson por la traducción Swift .
fuente
Me encontré con esta pregunta porque estaba teniendo un problema similar, pero usando Swift. Solo quería vincular a la respuesta que me funcionó para otros desarrolladores de Swift: https://stackoverflow.com/a/26676578/3904581
Aquí hay un fragmento de Swift que soluciona el problema de manera eficiente:
Super simple. Una línea de código. Problema resuelto.
fuente
Sé exactamente cuál es tu problema. Estás usando UIImagePicker, que es extraño en todos los sentidos. Le sugiero que use AVFoundation para la cámara, lo que brinda flexibilidad en la orientación y la calidad. Utilice AVCaptureSession. Puede obtener el código aquí. ¿Cómo guardar fotos tomadas con AVFoundation en un álbum de fotos?
fuente
Refactorizado rápidamente para Swift 3 (¿alguien puede probarlo y confirmar que todo funciona bien?):
fuente
Aquí está la versión Swift3 de la increíble respuesta de Dilip
fuente
Intente cambiar el formato de imagen a .jpeg. Esto funcionó para mi
fuente