Mój kod działa dobrze na normalnych urządzeniach, ale tworzy rozmyte obrazy na urządzeniach siatkówki.
Czy ktoś zna rozwiązanie mojego problemu?
+ (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContext(view.bounds.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Odpowiedzi:
Przełącz się z używania
UIGraphicsBeginImageContext
naUIGraphicsBeginImageContextWithOptions
(zgodnie z dokumentacją na tej stronie ). Podaj 0.0 dla skali (trzeci argument), a otrzymasz kontekst o współczynniku skali równym współczynnikowi ekranu.UIGraphicsBeginImageContext
używa stałego współczynnika skali wynoszącego 1,0, więc w rzeczywistości otrzymujesz dokładnie taki sam obraz na iPhonie 4 jak na innych iPhone'ach. Założę się, że iPhone 4 stosuje filtr, gdy domyślnie go skalujesz, lub po prostu twój mózg odbiera go jako mniej ostry niż wszystko wokół.Zgaduję:
A w Swift 4:
źródło
#import <QuartzCore/QuartzCore.h>
aby usunąćrenderInContext:
ostrzeżenie.UIImage
do ponownego załadowania, ale wymuszają wersję w wysokiej rozdzielczości (i prawdopodobnie natrafilibyście na problemy z powodu mniejszej pamięci RAM dostępnej w wersji wstępnej - urządzenia i tak).0.0f
parametru skali, czy jest bardziej akceptowalny w użyciu[[UIScreen mainScreen] scale]
, działa również.scale: The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
Jest wyraźnie udokumentowany, więc moim zdaniem 0.0f jest prostsze i lepsze.Akceptowana obecnie odpowiedź jest nieaktualna, przynajmniej jeśli wspierasz system iOS 7.
Oto, czego powinieneś używać, jeśli obsługujesz tylko iOS7 +:
Swift 4:
Zgodnie z tym artykułem widać, że nowa metoda iOS7
drawViewHierarchyInRect:afterScreenUpdates:
jest wielokrotnie szybsza niżrenderInContext:
.źródło
drawViewHierarchyInRect:afterScreenUpdates:
jest to o wiele szybsze. Właśnie uruchomiłem profiler czasu w Instrumentach. Moje generowanie obrazu wzrosło z 138 ms do 27 ms.afterScreenUpdates:
doYES
?viewDidLoad
lubviewWillAppear:
obrazy będą czarne; Musiałem to zrobićviewDidAppear:
. Więc w końcu wróciłem dorenderInContext:
.Stworzyłem rozszerzenie Swift oparte na rozwiązaniu @Dima:
EDYCJA: Swift 4 ulepszona wersja
Stosowanie:
źródło
class
funkcja ma widok?static
funkcja, ale ponieważ nie ma potrzeby zastępowania, możesz po prostu zmienić ją nastatic
func zamiastclass
.Korzystanie z nowoczesnego UIGraphicsImageRenderer
źródło
renderer
do staregodrawHierarchy
…?Aby poprawić odpowiedzi @Tommy i @Dima, użyj poniższej kategorii, aby renderować UIView w UIImage z przezroczystym tłem i bez utraty jakości. Praca na iOS7. (Lub po prostu użyj tej metody w implementacji, zastępując
self
odniesienie swoim obrazem)UIView + RenderViewToImage.h
UIView + RenderViewToImage.m
źródło
@interface
i@implementation
jak(RenderViewToImage)
i dodanie#import "UIView+RenderViewToImage.h"
do nagłówka wViewController.h
więc jest to poprawne wykorzystanie? na przykładUIImageView *test = [[UIImageView alloc] initWithImage:[self imageByRenderingView]]; [self addSubview:test];
?ViewController.m
był widok, który próbowałem renderować- (UIView *)testView { UIView *v1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)]; v1.backgroundColor = [UIColor redColor]; UIView *v2 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)]; v2.backgroundColor = [UIColor blueColor]; [v2 addSubview:v1]; return v2; }
Szybki 3
Rozwiązanie Swift 3 (oparte na odpowiedzi Dimy ) z rozszerzeniem UIView powinno wyglądać tak:
źródło
Drop-in Swift 3.0 rozszerzenie, które obsługuje nowy interfejs API iOS 10.0 i poprzednią metodę.
Uwaga:
!
co mogłoby spowodować awarię.źródło
Swift 2.0:
Za pomocą metody rozszerzenia:
Stosowanie:
źródło
Implementacja Swift 3.0
źródło
Wszystkie odpowiedzi Swift 3 nie działały dla mnie, dlatego przetłumaczyłem najbardziej akceptowaną odpowiedź:
źródło
Oto rozszerzenie Swift 4 UIView oparte na odpowiedzi z @Dima.
źródło
W przypadku Swift 5.1 możesz użyć tego rozszerzenia:
źródło
https://nshipster.com/image-resizing/
Upewnij się więc, że rozmiar, na który przechodzisz,
UIGraphicsImageRenderer
to punkty, a nie piksele.Jeśli twoje zdjęcia są większe niż się spodziewasz, musisz podzielić swój rozmiar przez współczynnik skali.
źródło
Czasami metoda drawRect sprawia problemy, więc otrzymałem te odpowiedzi bardziej odpowiednie. Ty też możesz na to spojrzeć. Capture UIImage z UIView utknął w metodzie DrawRect
źródło
źródło
W tej metodzie wystarczy przekazać obiekt widoku, a zwróci on obiekt UIImage.
źródło
Dodaj tę metodę do kategorii UIView
źródło