Ich habe den ganzen Tag daran gearbeitet und habe viele Fragen hier auf SO und google angeschaut, aber bis jetzt kann ich nichts richtig finden.
Ich habe ein Foto auf einem iPad mit iOS 5.1.1 gemacht und es mit der Fotos App zugeschnitten. Ich bekomme dann einen Verweis darauf aus der Objektbibliothek und erhalte das Bild mit voller Auflösung, das nicht beschnitten ist.
Ich habe festgestellt, dass die Informationen zum Zuschneiden in der AdjustmentXMP
-Schlüssel von metadata
auf meinem Objekt ALAssetRepresentation
enthalten sind.
Also beschneide ich das Foto mit den XMP-Infos und hier ist was ich bekomme:
Originalfoto (1.936 x 2.592):
Gut zugeschnittenes Foto, wie in der Fotos App (1.420 x 1.938) zu sehen:
Foto mit Code unten abgeschnitten
(auch 1,420 x 1,938, aber etwa 200 Pixel zu weit rechts abgeschnitten):
Dies sind die XMP-Daten vom Foto:
%Vor%Hier ist der Code, mit dem ich das Foto beschneide:
%Vor% Ich habe das Problem mit mehreren Bildern reproduziert. Wenn ich nur fullScreenImage
verwende, wird es perfekt angezeigt, aber ich brauche das Bild in voller Größe.
Das ist eine schwierige Frage! Es gibt offensichtlich keine Dokumentation für diese XMP-Daten, daher müssen wir raten, wie sie zu interpretieren ist. Es gibt eine Reihe von Wahlmöglichkeiten, und wenn man es falsch macht, kann dies zu leicht falschen Ergebnissen führen.
TL; DR: In der Theorie sieht dein Code korrekt aus, aber in der Praxis gibt es das falsche Ergebnis, und es gibt eine ziemlich offensichtliche Anpassung, die wir ausprobieren können.
Bilddateien können zusätzliche Metadaten enthalten, die angeben, ob (und wie) die Rohdaten des Bilds gedreht und / oder umgedreht werden sollen, wenn sie angezeigt werden. UIImage
drückt dies mit seiner imageOrientation
Eigenschaft und ALAssetRepresentation
ist ähnlich .
CGImage
s sind jedoch nur Bitmaps, in denen keine Ausrichtung gespeichert ist. -[ALAssetRepresentation fullResolutionImage]
gibt dir CGImage
in der ursprünglichen Ausrichtung, ohne dass Anpassungen vorgenommen wurden.
In Ihrem Fall lautet die Ausrichtung 3
, also ALAssetOrientationRight
oder UIImageOrientationRight
. Die Ansichtssoftware (z. B. UIImage
) berücksichtigt diesen Wert, erkennt, dass das Bild um 90 ° nach rechts (im Uhrzeigersinn) ausgerichtet ist, und dreht es dann um 90 ° nach links (gegen den Uhrzeigersinn), bevor es angezeigt wird. Oder, um es anders auszudrücken, das CGImage
wird um 90 ° im Uhrzeigersinn von dem Bild gedreht, das Sie auf Ihrem Bildschirm sehen.
(Um dies zu überprüfen, ermitteln Sie die Breite und Höhe von CGImage mit CGImageGetWidth()
und CGImageGetHeight()
. Sie sollten feststellen, dass CGImage 2592 breit und 1936 hoch ist. Dies ist um 90 ° von ALAssetRepresentation
gedreht. who dimensions
sollte 1936 wide um 2592 high sein Sie könnten auch eine UIImage
aus der CGImage
mit der normalen Ausrichtung UIImageOrientationUp
erstellen, schreiben Sie die UIImage
in eine Datei und sehen Sie, wie sie aussieht.)
Die Werte im XMP-Wörterbuch scheinen relativ zur Ausrichtung von CGImage
zu sein. Zum Beispiel ist die Crop-Rect breiter als hoch, die X-Translation ist größer als die Y-Translation, macht Sinn.
Wir müssen auch entscheiden, in welchem Koordinatensystem die XMP-Werte liegen sollen. Am wahrscheinlichsten ist es eines dieser beiden:
CGImageCreateWithImageInRect()
interpretiert das Argument rect
auf diese Weise. Nehmen wir an, dass "umgedreht" korrekt ist, da es im Allgemeinen bequemer ist. Dein Code versucht es ohnehin schon so.
Das Wörterbuch enthält eine affine Transformation und ein Crop-Rect. Lassen Sie uns raten, dass es in dieser Reihenfolge interpretiert werden sollte:
Wenn wir das von Hand versuchen, scheinen die Zahlen zu funktionieren. Hier ist ein grobes Diagramm, mit der Crop Rect in durchsichtigem Lila:
Wir müssen diese genauen Schritte in Bezug auf den Aufruf von CG nicht wirklich befolgen, aber wir sollten so tun, als ob wir hätten.
Wir wollen nur CGImageCreateWithImageInRect
aufrufen, und es ist ziemlich offensichtlich, wie man das richtige Crop rect (331,161,1938,1420)
berechnet. Dein Code scheint das richtig zu machen.
Wenn wir das Bild auf dieses Rechteck zuschneiden, dann erstellen wir ein UIImage
(unter Angabe der korrekten Ausrichtung, UIImageOrientationRight
), dann sollten wir die richtigen Ergebnisse erhalten.
Aber die Ergebnisse sind falsch! Was Sie erhalten haben, war als ob wir die Operationen in einem kartesischen Koordinatensystem ausgeführt hätten:
Alternativ verhält es sich so, als ob das Bild in die entgegengesetzte Richtung rotiert wurde, UIImageOrientationLeft
, aber wir haben dasselbe Bild rect beibehalten:
Das ist alles sehr merkwürdig, und ich verstehe nicht, was schiefgelaufen ist, obwohl ich es gerne tun würde.
Aber eine Lösung scheint ziemlich einfach zu sein: Einfach den Clip rect drehen. Nach der Berechnung wie oben:
%Vor%Funktioniert das? (Für diesen Fall und für Bilder mit anderen Orientierungen?)
Tags und Links objective-c ios alassetslibrary cgimage alasset