iOS Orientation d'Image a un Comportement Étrange
Depuis quelques semaines, j'ai travaillé avec des images en objective-c et de s'apercevoir beaucoup de comportement étrange. 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 un autre appareil photo et de MMS pour moi) sont pivotées de 90 degrés. Je n'étais pas sûr pourquoi, dans le monde de ce qui se passait (et donc ma question) mais j'ai été capable de trouver un bon travail.
Ma question cette fois est pourquoi est-ce qui se passe? Pourquoi Apple est la rotation d'image? Quand je prends une photo avec mon appareil photo en haut à droite, à moins que j'ai effectuer mon code mentionné ci-dessus, lorsque j'enregistre la photo il est sauvé de rotation. Maintenant, ma solution a été d'accord, jusqu'à il y a quelques jours.
Mon application modifie les pixels d'une image, plus précisément le canal alpha d'une image PNG (donc aucune conversion en JPEG obtient jeté hors de la fenêtre de 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 solution de contournement, quand mon algorithme modifie les différents pixels de l'image, elle pense que l'image est pivotée. Donc, 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 devrait être tourné)! Je peux pas comprendre comment le faire pivoter l'image dans la mémoire, dans l'idéal, je préfère juste essuyer que imageOrientation
drapeau tous ensemble.
Voici quelque chose d'autre qui a été déconcertant moi aussi... Quand je prends la photo, la imageOrientation
est fixé à 3. Ma solution de contournement code est assez intelligent pour comprendre cela et le retourner de sorte que l'utilisateur ne jamais avis. En outre, mon code pour enregistrer l'image de la bibliothèque s'en rend compte, il retourne, puis enregistre de sorte qu'il apparaît dans l'appareil photo rouler correctement.
Que le 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é dans mon application, le imageOrientation
est 0 - exactement ce que je veux voir, et ma rotation solution de contournement n'a même pas besoin de courir (remarque: lors du chargement d'images à partir d'internet, par opposition aux images prises avec un appareil photo, le imageOrientation
est toujours 0, résultant en parfait comportement). Pour une raison quelconque, mon enregistrer le code semble essuyer cette imageOrientation
drapeau. J'espérais juste voler que le code et l'utiliser pour essuyer mes imageOrientation dès que l'utilisateur prend une photo et l'a ajoutée à l'application, mais il ne semble pas fonctionner. Ne UIImageWriteToSavedPhotosAlbum
faire quelque chose de spécial avec imageOrientation
?
Serait la meilleure solution à ce problème est d'exploser imageOrientation
dès que l'utilisateur est fait en prenant une image. Je suppose que Apple a la rotation de comportement fait pour une raison, non? Quelques personnes ont suggéré que c'est une Pomme défaut.
(... si vous n'êtes pas encore perdu... Note2: Lorsque je prends une photo horizontale, tout semble fonctionner parfaitement, tout comme les photos prises à partir de l'internet)
EDIT:
Voici ce que certains des images et des scénarios ressemblent réellement. Basé sur les commentaires jusqu'à présent, il semble que ce comportement étrange est plus que juste un iPhone comportement, je pense que c'est bon.
C'est une image de la photo que j'ai prise avec mon téléphone (à noter la bonne orientation), il s'affiche exactement comme il l'a fait sur mon téléphone quand j'ai récupéré la photo:
Ici est ce que l'image ressemble à Gmail après j'ai envoyé un mail à moi-même (qui ressemble à Gmail gère correctement):
Voici ce que l'aspect de l'image sous forme de vignette dans windows (ne regarde pas comme il est manipulé correctement):
Et voici ce que l'image ressemble quand on ouvre 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 afficher correctement, il doit être tourné de 90 degrés". Cette information est dans les données EXIF. (Pourquoi il doit être tourné de 90 degrés, plutôt que la valeur par défaut droite verticale, je ne sais pas). À partir d'ici, Gmail est assez intelligent pour lire et analyser les données EXIF, et de l'afficher correctement. Windows cependant, n'est pas assez intelligent pour lire les données EXIF, et donc affiche l'image mal. Sont mes hypothèses correctes?
- Intéressant... si c'est vrai, pourquoi les images sont prises d'angle droit? Je sais que ce n'est pas un iPhone défaut, parce que j'ai remarqué le même comportement quand un ami (avec un BlackBerry) prend une image et MMS pour moi.
- Voir votre caméra écrit les métadonnées pour la faire tourner à 90 degrés, certains OS lire les métadonnées et le reste ne l'est pas.
- Assez bonne lecture (voir @Hadley réponse ci-dessous - dans un commentaire). Donc, mon appli est clair, doit être assez intelligent pour gérer les images qui contiennent des données EXIF, ainsi que des images qui ne contiennent pas de lui... je ne comprends toujours pas pourquoi quand je prends une photo en haut à droite, l'orientation drapeau dit qu'il doit être tourné de 90 degrés?
- Vous définissez votre photo en mode Portrait, et vous n'êtes pas une rotation de la caméra à l'angle droit ou le mode Paysage et la caméra a capturé l'image dans l'angle droit de la position, le capteur de définir automatiquement l'orientation appropriée. Check it out
- La Solution est plus probablement , votre application doit lire les méta-données et rotation de l'image et/ou de modifier les métadonnées selon l'exigence.
- Découvrez mon montage. J'ai ajouté des images à montrer exactement ce que je vois. Est mon hypothèse correcte, que le comportement est tout à fait prévu, c'est juste jusqu'à la fin de l'application pour déterminer comment afficher l'image?
- Je vois cela devenir un énorme problème pour moi. J'ai fait un site web à l'aide de Thème. Ajout d'éléments dans le marché via un ipad (prendre des photos sur l'ipad) est à l'origine des images à afficher dans le magasin avec une rotation de 90 degrés vers la gauche, où elles apparaissent sur un appareil mobile à l'amende juste.
Vous devez vous connecter pour publier un commentaire.
Je l'ai fait R&D sur elle et de découvrir , chaque fichier d'image a des propriétés de métadonnées. Si les métadonnées spécifie l'orientation de l'image qui est généralement ignoré par les autres OS mais Mac. La plupart des images prises sont d'avoir leurs méta-données de jeu de propriétés à angle droit. Donc les Mac montre rotation de 90 degrés manière. Vous pouvez voir la même image de manière adéquate dans l'OS de windows.
Pour plus de détails, lisez cette réponse http://graphicssoft.about.com/od/digitalphotography/f/sideways-pictures.htm
essayez de lire votre image exif ici http://www.exifviewer.org/ , ou http://regex.info/exif.cgi , ou http://www.addictivetips.com/internet-tips/view-complete-exif-metadata-information-of-any-jpeg-image-online/
J'ai eu le même problème quand je reçois l'image de la Caméra, j'ai mis le code suivant pour le fixer.. Ajout de la méthode scaleAndRotateImage à partir d'ici
bounds.size.height.round()
etbounds.size.width.round()
(c'est rapide, syntaxe, je ne sais pas comment l'écrire en Obj-C)Rapide copier/coller Swift traduction de Dilip de excellente réponse.
Swift 4 version avec les contrôles de sécurité de Dilip réponse.
(bounds.size.height, bounds.size.width) = (bounds.size.width, bounds.size.height)
sans créer de variable comme espace de stockage.bounds.size.height.round()
etbounds.size.width.round()
Une image généré par l'iPhone/iPad est enregistré en tant que Paysage Gauche avec la balise EXIF (Exif.Image.L'Orientation) en précisant la réelle orientation.
Il avoir les valeurs suivantes:
1 : Le Paysage De Gauche
6 : Portrait Normal
3 : Le Paysage À Droite
4 : Portrait À L'Envers
Dans IOS, l'information EXIF de lire correctement et les images sont affichées de la même manière qu'il a été pris. Mais dans Windows, les données EXIF n'est PAS utilisé.
Si vous ouvrez l'une de ces images dans GIMP, il va dire que l'image a la rotation info.
La réponse à cela est très simple. Apple n'est PAS la rotation de l'image. C'est là que la confusion réside.
Le CCD de la caméra ne tourne pas, il est donc toujours prendre une photo en mode paysage.
Apple a fait une chose très judicieuse - au lieu de passer tout le temps pour faire pivoter l'image de brassage mégaoctets de données - juste le tag avec la FAÇON dont la photo a été prise.
OpenGL n'est des traductions très facilement de sorte que les DONNÉES n'est jamais mélangé - juste à la FAÇON de SON TRACÉ.
D'où l'orientation de meta-données.
Cela devient un problème si vous souhaitez recadrer, redimensionner, etc - mais une fois que vous savez ce qui se passe, il vous suffit de définir votre matrice et tout fonctionne.
Pour quelqu'un d'autre à l'aide de Xamarin, voici un C# traduction de Dilip de grande réponse, et grâce à thattyson pour la Swift traduction.
Je suis tombé sur cette question, car j'ai eu un problème similaire, mais l'utilisation de Swift. Voulais juste le lien vers la réponse qui a fonctionné pour moi pour tout autre Swift développeurs: https://stackoverflow.com/a/26676578/3904581
Voici un rapide extrait de code qui résout le problème de manière efficace:
Super simple. Une seule ligne de code. Le problème est résolu.
Je sais exactement quel est ton problème. Vous utilisez UIImagePicker, ce qui est étrange dans tous les sens. Je vous suggère d'utiliser AVFoundation de la caméra qui donne de la flexibilité dans l'orientation ainsi que sur la qualité. Utilisation AVCaptureSession.
Vous pouvez obtenir le code ici Comment enregistrer des photos prises à l'aide de AVFoundation à un Album Photo?
Rapidement remaniée pour Swift 3 (quelqu'un peut tester et confirmer tout fonctionne ok?):
Ici est Swift3 version de Dilip est génial réponse
Essayez de changer le format de la photo .jpeg. Cela a fonctionné pour moi