Mam kod, który zmienia rozmiar obrazu, dzięki czemu mogę uzyskać przeskalowaną część środka obrazu - używam tego, aby zrobić UIImage
i zwrócić małą, kwadratową reprezentację obrazu, podobną do tego, co widać w widoku albumu aplikacja Zdjęcia. (Wiem, że mogłem użyć a UIImageView
i dostosować tryb przycinania, aby uzyskać te same wyniki, ale te obrazy są czasami wyświetlane w UIWebViews
).
Zacząłem zauważać awarie w tym kodzie i jestem trochę zakłopotany. Mam dwie różne teorie i zastanawiam się, czy któraś z nich jest oparta.
Teoria 1) Kadrowanie osiągam, rysując w kontekście obrazu poza ekranem mojego docelowego rozmiaru. Ponieważ chcę środkowej części obrazu, ustawiłem CGRect
argument przekazywany drawInRect
na coś, co jest większe niż granice mojego kontekstu obrazu. Miałem nadzieję, że to koszerne, ale czy zamiast tego próbuję przywołać inne wspomnienia, których nie powinienem dotykać?
Teoria 2) Robię to wszystko w tle. Wiem, że istnieją części UIKit, które są ograniczone do głównego wątku. Zakładałem / miałem nadzieję, że rysowanie w widoku poza ekranem nie było jednym z nich. Czy się mylę?
(Och, jak tęsknię za NSImage's drawInRect:fromRect:operation:fraction:
metodą.)
Odpowiedzi:
Aktualizacja 2014-05-28: Napisałem to, gdy iOS 3 lub coś takiego było nowością, jestem pewien, że istnieją lepsze sposoby, aby to zrobić, być może wbudowane. Jak wspomniało wiele osób, ta metoda nie uwzględnia rotacji; przeczytaj kilka dodatkowych odpowiedzi i rozpowszechnij miłość, aby odpowiedzi na to pytanie były pomocne dla wszystkich.
Oryginalna odpowiedź:
Skopiuję / wkleję swoją odpowiedź na to samo pytanie w innym miejscu:
Nie ma prostej metody klasy, aby to zrobić, ale istnieje funkcja, której można użyć, aby uzyskać pożądane wyniki:
CGImageCreateWithImageInRect(CGImageRef, CGRect)
pomoże ci.Oto krótki przykład korzystania z niego:
źródło
imageOrientation
jest ustawiony na cokolwiek innego niż w górę,CGImage
obraca się względemUIImage
prostokąta przycinania i będzie nieprawidłowy. Możesz odpowiednio obrócić prostokąt przycinania, ale świeżo utworzonyUIImage
będzie miałimageOrientation
górę, dzięki czemu przycięteCGImage
zostaną obrócone w nim.[UIImage imageWithCGImage:imageRef scale:largeImage.scale orientation:largeImage.imageOrientation];
Aby przyciąć obrazy siatkówki przy zachowaniu tej samej skali i orientacji, użyj następującej metody w kategorii UIImage (iOS 4.0 i wyżej):
źródło
self.scale
, nie?CGImageRelease(imageRef);
z ARC jest prawidłowe ?Możesz stworzyć kategorię UIImage i używać jej tam, gdzie potrzebujesz. Na podstawie odpowiedzi HitScans i komentarzy poniżej.
Możesz użyć tego w ten sposób:
źródło
[[UIScreen mainScreen] scale]
tak byćself.scale
? Skala obrazu może nie być taka sama jak skala ekranu.No visible @interface for 'UIImage' declares the selector 'crop'
mimo że umieściłem pliki kategorii .h i .m w moim projekcie i zaimportowałem .h do klasy, której używam kategorii. Dowolny pomysł?Wersja Swift 3
za pomocą tej funkcji mostka
CGRectMake
->CGRect
(na tę odpowiedź odpowiedział:)@rob mayoff
:Wykorzystanie jest:
Wynik:
źródło
guard
do pierwszego wiersza na wypadekUIImage.CGImage
powrotunil
i dlaczego używać,var
gdylet
działa idealnie.cropping(to:)
bardzo uważnie czytaj dokumentację . WynikowyCGImage
ma silne odniesienie do większego,CGImage
z którego został przycięty. Jeśli więc chcesz trzymać się tylko przyciętego obrazu i nie potrzebujesz oryginału, spójrz na inne rozwiązania.right
cgImage powinien zostać obrócony o 90 stopni w kierunku przeciwnym do kierunku jazdy, dlatego też należy obrócić prostokąt przycinaniaOto moja implementacja przycinania UIImage, która jest zgodna z właściwością imageOrientation. Wszystkie orientacje zostały dokładnie przetestowane.
źródło
implicit declaration of function 'rad' is invalid in c99
można usunąć, zastępując: rad (90), rad (-90), rad (-180) -> M_PI_2, -M_PI_2, -_M_PIcontains undefined reference for architecture armv7
Czy brakuje mi biblioteki? CoreGraphics jest importowany.CGImage
Uwaga : wszystkie te odpowiedzi zakładają obiekt obrazu z cofnięciem.image.CGImage
może zwrócić zero, jeśliUIImage
jest on wspierany przez aCIImage
, co miałoby miejsce, gdybyś utworzył ten obraz za pomocąCIFilter
.W takim przypadku konieczne może być narysowanie obrazu w nowym kontekście i zwrócenie tego obrazu ( powoli ).
źródło
Żadna z odpowiedzi tutaj nie obsługuje wszystkich problemów ze skalą i rotacją w 100% poprawnie. Oto synteza wszystkiego, co powiedziane do tej pory, aktualne na iOS7 / 8. Ma być włączony jako metoda do kategorii w UIImage.
źródło
Szybka wersja
awolf
odpowiedzi, która zadziałała dla mnie:źródło
Większość odpowiedzi, które widziałem, dotyczy tylko pozycji (0, 0) dla (x, y). Ok, to jest jeden przypadek, ale chciałbym, aby moja operacja przycinania była wyśrodkowana. To, co zajęło mi trochę czasu, aby zrozumieć, to wiersz następujący po komentarzu WTF.
Weźmy przypadek zdjęcia wykonanego w orientacji pionowej:
Mam nadzieję, że to ma sens! Jeśli nie, wypróbuj inne wartości, a zobaczysz, że logika jest odwrócona, jeśli chodzi o wybór właściwego x, y, szerokości i wysokości dla twojego cropRect.
źródło
swift3
źródło
Szybkie rozszerzenie
źródło
Najlepsze rozwiązanie do przycinania obrazu UII w Swift pod względem precyzji, skalowania pikseli ...:
Instrukcje użyte do wywołania tej funkcji:
Uwaga: początkowa inspiracja kodu źródłowego napisana w Objective-C została znaleziona na blogu „Cocoanetics”.
źródło
Poniższy fragment kodu może pomóc.
źródło
Wygląda trochę dziwnie, ale działa świetnie i uwzględnia orientację obrazu:
źródło
Swift 5:
źródło
źródło
źródło
W iOS9.2SDK używam poniższej metody do konwersji ramki z UIView na UIImage
źródło
Aktualizacja Swift 2.0 (
CIImage
kompatybilność)Rozszerzanie odpowiedzi Maxima, ale działa również, jeśli Twój obraz jest
CIImage
oparty.źródło
Oto zaktualizowana wersja Swift 3 oparta na odpowiedzi Noodles
źródło
Postępuj zgodnie z odpowiedzią @Arne. Właśnie ustawiam na funkcję kategorii. umieść go w kategorii UIImage.
źródło
Nie byłem usatysfakcjonowany innymi rozwiązaniami, ponieważ albo rysują kilka razy (zużywają więcej energii niż to konieczne), albo mają problemy z orientacją. Oto, czego użyłem do skalowanego kwadratu przyciętego obrazu z obrazu UIImage *.
źródło
Korzystam z metody poniżej.
}
źródło
Spójrz na https://github.com/vvbogdan/BVCropPhoto
źródło