Au cours des dernières semaines, j'ai travaillé avec des images en objective-c et j'ai remarqué beaucoup de comportements étranges. Tout d'abord, comme beaucoup d'autres personnes, j'ai eu ce problème où les images prises avec l'appareil photo (ou prises avec l'appareil photo de quelqu'un d'autre et le MMS vers moi) sont pivotées de 90 degrés. Je ne savais pas pourquoi dans le monde cela se produisait (d'où ma question ) mais j'ai pu trouver un travail bon marché.
Ma question cette fois est pourquoi cela se produit-il ? Pourquoi Apple fait-il pivoter les images? Lorsque je prends une photo avec mon appareil photo à l'endroit, à moins d'exécuter le code mentionné ci-dessus, lorsque j'enregistre la photo, elle est enregistrée en rotation. Maintenant, ma solution de contournement était correcte jusqu'à il y a quelques jours.
Mon application modifie les pixels individuels d'une image, en particulier le canal alpha d'un PNG (ainsi toute conversion JPEG est jetée hors de la fenêtre pour mon scénario). Il y a quelques jours, j'ai remarqué que même si l'image s'affiche correctement dans mon application grâce à mon code de contournement, lorsque mon algorithme modifie les pixels individuels de l'image, il pense que l'image est tournée. Alors au lieu de modifier les pixels en haut de l'image, il modifie les pixels sur le côté de l'image (car il pense qu'il faut la faire pivoter)! Je ne peux pas comprendre comment faire pivoter l'image en mémoire - idéalement, je préférerais simplement effacer ce imageOrientation
drapeau tous ensemble.
Voici quelque chose d'autre qui m'a également déconcerté ... Lorsque je prends la photo, le imageOrientation
est réglé sur 3. Mon code de contournement est assez intelligent pour réaliser cela et le retourner afin que l'utilisateur ne le remarque jamais. De plus, mon code pour enregistrer l'image dans la bibliothèque le réalise, le retourne, puis l' enregistre pour qu'il apparaisse correctement dans la pellicule.
Ce code ressemble à ceci:
NSData* pngdata = UIImagePNGRepresentation (self.workingImage); //PNG wrap
UIImage* img = [self rotateImageAppropriately:[UIImage imageWithData:pngdata]];
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
Lorsque je charge cette image nouvellement enregistrée dans mon application, la valeur imageOrientation
est 0 - exactement ce que je veux voir, et ma solution de contournement de rotation n'a même pas besoin de s'exécuter (remarque: lors du chargement d'images depuis Internet par opposition aux images prises avec un appareil photo , la imageOrientation
vaut toujours 0, ce qui donne un comportement parfait). Pour une raison quelconque, mon code de sauvegarde semble effacer cet imageOrientation
indicateur. J'espérais simplement voler ce code et l'utiliser pour effacer mon imageOrientation dès que l'utilisateur prend une photo et l'ajoute à l'application, mais cela ne semble pas fonctionner. Fait UIImageWriteToSavedPhotosAlbum
quelque chose de spécial avec imageOrientation
?
La meilleure solution à ce problème serait-elle de simplement souffler imageOrientation
dès que l'utilisateur a terminé de prendre une image. Je suppose qu'Apple a fait le comportement de rotation pour une raison, non? Quelques personnes ont suggéré qu'il s'agissait d'un défaut Apple.
(... si vous n'êtes pas encore perdu ... Note 2: Quand je prends une photo horizontale, tout semble fonctionner parfaitement, tout comme les photos prises sur Internet)
ÉDITER:
Voici à quoi ressemblent réellement certaines images et scénarios. Sur la base des commentaires jusqu'à présent, il semble que ce comportement étrange est plus qu'un simple comportement d'iPhone, ce que je pense être bon.
Ceci est une photo de la photo que j'ai prise avec mon téléphone (notez l'orientation correcte), elle apparaît exactement comme elle le faisait sur mon téléphone lorsque j'ai pris la photo:
Voici à quoi ressemble l'image dans Gmail une fois que je l'ai envoyée par courrier électronique (on dirait que Gmail la gère correctement):
Voici à quoi ressemble l'image sous forme de vignette dans les fenêtres (ne semble pas être gérée correctement):
Et voici à quoi ressemble l'image réelle lorsqu'elle est ouverte avec la visionneuse de photos Windows (toujours pas gérée correctement):
Après tous les commentaires sur cette question, voici ce que je pense ... L'iPhone prend une image, et dit "pour l'afficher correctement, il doit être tourné de 90 degrés". Ces informations figureraient dans les données EXIF. (Pourquoi il doit être tourné de 90 degrés, plutôt que de passer par défaut à la verticale droite, je ne sais pas). À partir de là, Gmail est suffisamment intelligent pour lire et analyser ces données EXIF et les afficher correctement. Cependant, Windows n'est pas assez intelligent pour lire les données EXIF et affiche donc l'image de manière incorrecte . Mes hypothèses sont-elles correctes?
la source
Réponses:
J'ai fait de la R&D dessus et j'ai découvert que chaque fichier image avait une propriété de métadonnées. Si les métadonnées spécifient l'orientation de l'image qui est généralement ignorée par d'autres OS mais Mac. La plupart des images prises ont leur propriété de métadonnées définie sur l'angle droit. Donc Mac le montre de manière pivotée à 90 degrés. Vous pouvez voir la même image de manière appropriée dans le système d'exploitation Windows.
Pour plus de détails, lisez cette réponse http://graphicssoft.about.com/od/digitalphotography/f/sideways-pictures.htm
essayez de lire l'exif de votre image ici http://www.exifviewer.org/ , ou http://regex.info/exif.cgi , ou http://www.addictivetips.com/internet-tips/view-complete-exif -métadonnées-informations-de-toute-image-jpeg-en ligne /
la source
J'ai eu le même problème lorsque j'obtiens l'image de Camera, j'ai mis le code suivant pour le réparer .. Ajout de la méthode scaleAndRotateImage à partir d'ici
la source
Copier / coller rapide Traduction rapide de l' excellente réponse de Dilip .
la source
La réponse à cela est très simple. Apple ne fait PAS pivoter l'image. C'est là que réside la confusion.
La caméra CCD ne tourne pas, elle prend donc toujours la photo en mode paysage.
Apple a fait une chose très intelligente - au lieu de passer tout le temps à faire pivoter l'image - en mélangeant des mégaoctets de données - il suffit de marquer avec COMMENT la photo a été prise.
OpenGL fait des traductions très facilement - donc les DONNÉES ne sont jamais mélangées - juste COMMENT ILS SONT DESSINÉES.
D'où les métadonnées d'orientation.
Cela devient un problème si vous voulez recadrer, redimensionner, etc. - mais une fois que vous savez ce qui se passe, vous définissez simplement votre matrice et tout fonctionne.
la source
Version Swift 4 avec contrôles de sécurité de la réponse de Dilip .
la source
(bounds.size.height, bounds.size.width) = (bounds.size.width, bounds.size.height)
passer de la création de variable comme stockage.bounds.size.height.round()
etbounds.size.width.round()
Toute image générée par iPhone / iPad est enregistrée en tant que Paysage à gauche avec une balise d'orientation EXIF (Exif.Image.Orientation) spécifiant l'orientation réelle.
Il a les valeurs suivantes: 1: Paysage à gauche 6: Portrait Normal 3: Paysage à droite 4: Portrait à l'envers
Dans IOS, les informations EXIF sont correctement lues et les images sont affichées de la même manière qu'elles ont été prises. Mais sous Windows, les informations EXIF ne sont PAS utilisées.
Si vous ouvrez l'une de ces images dans GIMP, cela indiquera que l'image a des informations de rotation.
la source
Pour tous ceux qui utilisent Xamarin, voici une traduction C # de l' excellente réponse de Dilip , et un merci à thattyson pour la traduction Swift .
la source
Je suis tombé sur cette question parce que j'avais un problème similaire, mais en utilisant Swift. Je voulais juste faire un lien vers la réponse qui a fonctionné pour moi pour tous les autres développeurs Swift: https://stackoverflow.com/a/26676578/3904581
Voici un extrait de code Swift qui résout efficacement le problème:
Super simple. Une ligne de code. Problème résolu.
la source
Je sais exactement quel est votre problème. Vous utilisez UIImagePicker, ce qui est étrange dans tous les sens du terme. Je vous suggère d'utiliser AVFoundation pour la caméra, ce qui donne une flexibilité d'orientation ainsi que de qualité. Utilisez AVCaptureSession. Vous pouvez obtenir le code ici Comment enregistrer des photos prises avec AVFoundation dans un album photo?
la source
Refactorisé rapidement pour Swift 3 (quelqu'un peut-il le tester et confirmer que tout fonctionne bien?):
la source
Voici la version Swift3 de la réponse géniale de Dilip
la source
Essayez de changer le format d'image en .jpeg. Cela a fonctionné pour moi
la source