Mein Code funktioniert gut für normale Geräte, erzeugt jedoch verschwommene Bilder auf Retina-Geräten.
Kennt jemand eine Lösung für mein Problem?
+ (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContext(view.bounds.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Antworten:
Wechseln Sie von Verwendung
UIGraphicsBeginImageContext
zuUIGraphicsBeginImageContextWithOptions
(wie auf dieser Seite dokumentiert ). Übergeben Sie 0.0 für scale (das dritte Argument) und Sie erhalten einen Kontext mit einem Skalierungsfaktor, der dem des Bildschirms entspricht.UIGraphicsBeginImageContext
verwendet einen festen Skalierungsfaktor von 1,0, sodass Sie auf einem iPhone 4 genau das gleiche Bild erhalten wie auf den anderen iPhones. Ich wette, entweder das iPhone 4 wendet einen Filter an, wenn Sie ihn implizit vergrößern, oder nur Ihr Gehirn erkennt, dass er weniger scharf ist als alles um ihn herum.Also, ich denke:
Und in Swift 4:
quelle
#import <QuartzCore/QuartzCore.h>
, um dierenderInContext:
Warnung zu entfernen .UIImage
festhalten , anzuweisen, neu zu laden, sondern die hochauflösende Version zu erzwingen (und Sie wahrscheinlich auf Probleme stoßen würden, weil weniger RAM vorab verfügbar ist -retina Geräte sowieso).0.0f
den Parameter for for scale zu verwenden, ist die Verwendung akzeptabler[[UIScreen mainScreen] scale]
und funktioniert auch.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.
Es ist explizit dokumentiert, daher ist 0.0f meiner Meinung nach einfacher und besser.Die derzeit akzeptierte Antwort ist veraltet, zumindest wenn Sie iOS 7 unterstützen.
Folgendes sollten Sie verwenden, wenn Sie nur iOS7 + unterstützen:
Swift 4:
In diesem Artikel sehen Sie, dass die neue iOS7-Methode
drawViewHierarchyInRect:afterScreenUpdates:
um ein Vielfaches schneller ist alsrenderInContext:
.quelle
drawViewHierarchyInRect:afterScreenUpdates:
ist viel schneller. Ich habe gerade einen Zeitprofiler in Instruments ausgeführt. Meine Bilderzeugung ging von 138 ms auf 27 ms.afterScreenUpdates:
auf einzustellenYES
?viewDidLoad
oderviewWillAppear:
die Bilder schwarz sind; Ich musste es tunviewDidAppear:
. Also bin ich auch endlich zurückgekehrtrenderInContext:
.Ich habe eine Swift-Erweiterung basierend auf der @ Dima-Lösung erstellt:
EDIT: Swift 4 verbesserte Version
Verwendungszweck:
quelle
class
Funktion, die eine Ansicht vertritt?static
Funktion, aber da keine Überschreibung erforderlich ist, können Sie sie einfach in eine Funktionstatic
anstelle von ändernclass
.Verwendung des modernen UIGraphicsImageRenderer
quelle
renderer
zur alten istdrawHierarchy
?Um die Antworten von @Tommy und @Dima zu verbessern, verwenden Sie die folgende Kategorie, um UIView mit transparentem Hintergrund und ohne Qualitätsverlust in UIImage zu rendern . Arbeiten an iOS7. (Oder verwenden Sie diese Methode einfach in der Implementierung wieder und ersetzen Sie die
self
Referenz durch Ihr Bild.)UIView + RenderViewToImage.h
UIView + RenderViewToImage.m
quelle
@interface
und@implementation
beide(RenderViewToImage)
und das Hinzufügen#import "UIView+RenderViewToImage.h"
zu dem Header inViewController.h
so ist dies die korrekte Verwendung? zBUIImageView *test = [[UIImageView alloc] initWithImage:[self imageByRenderingView]]; [self addSubview:test];
?ViewController.m
war die Ansicht, die ich zu rendern versuchte- (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; }
Swift 3
Die Swift 3- Lösung (basierend auf Dimas Antwort ) mit UIView-Erweiterung sollte folgendermaßen aussehen:
quelle
Drop-in Swift 3.0-Erweiterung, die die neue iOS 10.0-API und die vorherige Methode unterstützt.
Hinweis:
!
was zu einem Absturz führen könnte.quelle
Swift 2.0:
Verwenden der Erweiterungsmethode:
Verwendungszweck:
quelle
Schnelle 3.0-Implementierung
quelle
Alle Swift 3-Antworten haben bei mir nicht funktioniert, daher habe ich die am meisten akzeptierte Antwort übersetzt:
quelle
Hier ist eine Swift 4 UIView-Erweiterung, die auf der Antwort von @Dima basiert.
quelle
Für Swift 5.1 können Sie diese Erweiterung verwenden:
quelle
https://nshipster.com/image-resizing/
UIGraphicsImageRenderer
Stellen Sie also sicher, dass die Größe, in die Sie übergeben, Punkte und keine Pixel sind.Wenn Ihre Bilder größer sind als erwartet, müssen Sie Ihre Größe durch den Skalierungsfaktor teilen.
quelle
Manchmal macht die drawRect-Methode ein Problem, daher habe ich diese Antworten besser erhalten. Vielleicht sehen auch Sie es sich an. Erfassen Sie UIImage von UIView, das in der DrawRect-Methode steckt
quelle
quelle
Bei dieser Methode übergeben Sie einfach ein Ansichtsobjekt und es wird ein UIImage-Objekt zurückgegeben.
quelle
Fügen Sie diese Methode zur UIView-Kategorie hinzu
quelle