Ich habe einen Code, der die Größe eines Bildes ändert, damit ich einen skalierten Teil der Bildmitte erhalten kann. Ich verwende diesen Code, UIImage
um eine kleine, quadratische Darstellung eines Bildes aufzunehmen und zurückzugeben, ähnlich wie in der Albumansicht von die Fotos App. (Ich weiß, ich könnte a verwenden UIImageView
und den Zuschneidemodus anpassen, um die gleichen Ergebnisse zu erzielen, aber diese Bilder werden manchmal in angezeigt UIWebViews
).
Ich habe angefangen, einige Abstürze in diesem Code zu bemerken und bin ein bisschen ratlos. Ich habe zwei verschiedene Theorien und frage mich, ob beide auf der Basis sind.
Theorie 1) Ich erreiche das Zuschneiden, indem ich in einen Offscreen-Bildkontext meiner Zielgröße zeichne. Da ich den mittleren Teil des Bildes haben möchte, setze ich das CGRect
Argument an drawInRect
etwas, das größer ist als die Grenzen meines Bildkontexts. Ich hatte gehofft, dass dies koscher ist, aber versuche ich stattdessen, andere Erinnerungen zu erfassen, die ich nicht berühren sollte?
Theorie 2) Ich mache das alles in einem Hintergrund-Thread. Ich weiß, dass es Teile von UIKit gibt, die auf den Haupt-Thread beschränkt sind. Ich ging davon aus / hoffte, dass das Zeichnen in eine Offscreen-Ansicht nicht dazu gehört. Liege ich falsch?
(Oh, wie ich NSImage's drawInRect:fromRect:operation:fraction:
Methode vermisse .)
Antworten:
Update 28.05.2014: Ich habe dies geschrieben, als iOS 3 oder so das heiße neue Ding war. Ich bin mir sicher, dass es jetzt bessere Möglichkeiten gibt, dies zu tun, möglicherweise eingebaut. Wie viele Leute erwähnt haben, berücksichtigt diese Methode keine Rotation; Lesen Sie einige zusätzliche Antworten und verbreiten Sie ein wenig Liebe, um die Antworten auf diese Frage für alle hilfreich zu halten.
Ursprüngliche Antwort:
Ich werde meine Antwort auf dieselbe Frage an anderer Stelle kopieren / einfügen:
Es gibt keine einfache Klassenmethode, um dies zu tun, aber es gibt eine Funktion, mit der Sie die gewünschten Ergebnisse erzielen können: Sie
CGImageCreateWithImageInRect(CGImageRef, CGRect)
wird Ihnen helfen.Hier ist ein kurzes Beispiel:
quelle
imageOrientation
auf etwas anderes als nach oben eingestellt ist, wird dasCGImage
in Bezug auf das gedrehtUIImage
und das zugeschnittene Rechteck ist falsch. Sie können das Beschneidungsrechteck entsprechend drehen, aber die frisch erstelltenUIImage
habenimageOrientation
, so dass die beschnitteneCGImage
Inneren gedreht wird.[UIImage imageWithCGImage:imageRef scale:largeImage.scale orientation:largeImage.imageOrientation];
Verwenden Sie die folgende Methode in einer UIImage-Kategorie (iOS 4.0 und höher), um Retina-Bilder bei gleichem Maßstab und gleicher Ausrichtung zuzuschneiden:
quelle
self.scale
, nein?CGImageRelease(imageRef);
mit aktiviertem ARC zu verwenden ?Sie können eine UIImage-Kategorie erstellen und überall dort verwenden, wo Sie sie benötigen. Basierend auf der Antwort von HitScans und den Kommentaren unten.
Sie können es folgendermaßen verwenden:
quelle
[[UIScreen mainScreen] scale]
einfach so seinself.scale
? Der Maßstab des Bildes stimmt möglicherweise nicht mit dem Maßstab des Bildschirms überein.No visible @interface for 'UIImage' declares the selector 'crop'
, obwohl ich die Kategoriedateien .h und .m in mein Projekt eingefügt und die .h in die Klasse importiert habe, in der ich die Kategorie verwende. Irgendeine Idee?Swift 3 Version
mit Hilfe dieser Brückenfunktion
CGRectMake
->CGRect
(Credits zu dieser Antwort beantwortet von@rob mayoff
):Die Verwendung ist:
Ausgabe:
quelle
guard
die erste Zeile gehen, fallsUIImage.CGImage
zurückgegeben wirdnil
und warum verwendet wird,var
wenn eslet
perfekt funktioniert.cropping(to:)
sehr sorgfältig durch. Das ErgebnisCGImage
enthält einen starken Bezug zu dem größeren,CGImage
von dem es abgeschnitten wurde. Wenn Sie also nur am zugeschnittenen Bild festhalten möchten und kein Original benötigen, schauen Sie sich die anderen Lösungen an.right
sollte das cgImage um 90 Grad gedreht werden, daher sollte auch das Crop Rect gedreht werdenHier ist meine UIImage-Crop-Implementierung, die der imageOrientation-Eigenschaft folgt. Alle Orientierungen wurden gründlich getestet.
quelle
implicit declaration of function 'rad' is invalid in c99
kann durch Ersetzen entfernt werden: rad (90), rad (-90), rad (-180) -> M_PI_2, -M_PI_2, -_M_PIcontains undefined reference for architecture armv7
Vermisse ich eine Bibliothek? CoreGraphics wird importiert.Heads up: Alle diese Antworten setzen ein
CGImage
Bildobjekt mit Unterstützung voraus.image.CGImage
kann nil zurückgeben, wenn dasUIImage
von a unterstützt wirdCIImage
, was der Fall wäre, wenn Sie dieses Bild mit a erstellen würdenCIFilter
.In diesem Fall müssen Sie das Bild möglicherweise in einem neuen Kontext zeichnen und das Bild zurückgeben ( langsam ).
quelle
Keine der Antworten hier behandelt alle Skalierungs- und Rotationsprobleme zu 100% korrekt. Hier ist eine Synthese von allem, was bisher gesagt wurde und ab iOS7 / 8 aktuell ist. Es soll als Methode in eine Kategorie auf UIImage aufgenommen werden.
quelle
Schnelle Version von
awolf
's Antwort, die für mich funktioniert hat:quelle
Die meisten Antworten, die ich gesehen habe, befassen sich nur mit einer Position von (0, 0) für (x, y). Ok, das ist ein Fall, aber ich möchte, dass mein Zuschneidevorgang zentriert wird. Was ich eine Weile gebraucht habe, um herauszufinden, ist die Zeile nach dem WTF-Kommentar.
Nehmen wir den Fall eines Bildes, das im Hochformat aufgenommen wurde:
Hoffe es macht Sinn! Wenn dies nicht der Fall ist, probieren Sie verschiedene Werte aus. Sie werden feststellen, dass die Logik invertiert ist, wenn Sie das richtige x, y, die richtige Breite und Höhe für Ihr cropRect auswählen.
quelle
swift3
quelle
Schnelle Erweiterung
quelle
Beste Lösung zum Zuschneiden eines UIImage in Swift , in Bezug auf Genauigkeit, Pixel-Skalierung ...:
Anweisungen zum Aufrufen dieser Funktion:
Hinweis: Die erste in Objective-C geschriebene Inspiration für den Quellcode wurde im Blog "Cocoanetics" gefunden.
quelle
Das folgende Code-Snippet könnte helfen.
quelle
Sieht etwas seltsam aus, funktioniert aber hervorragend und berücksichtigt die Bildorientierung:
quelle
Swift 5:
quelle
quelle
quelle
Unter iOS9.2SDK verwende ich die folgende Methode, um Frames von UIView in UIImage zu konvertieren
quelle
Swift 2.0 Update (
CIImage
Kompatibilität)Erweitern von Maxim's Answer , funktioniert aber auch, wenn Ihr Bild
CIImage
basiert.quelle
Hier ist eine aktualisierte Swift 3-Version, die auf der Antwort von Noodles basiert
quelle
Folgen Sie der Antwort von @Arne. Ich behebe mich nur auf die Kategoriefunktion. stelle es in die Kategorie von UIImage.
quelle
Ich war mit anderen Lösungen nicht zufrieden, weil sie entweder mehrmals zeichnen (mehr Strom verbrauchen als nötig) oder Probleme mit der Orientierung haben. Folgendes habe ich für ein skaliertes quadratisches CroppedImage aus einem UIImage * -Bild verwendet.
quelle
Ich benutze die Methode unten.
}}
quelle
Schauen Sie sich https://github.com/vvbogdan/BVCropPhoto an
quelle