So konvertieren Sie eine UIView in ein Bild

93

Ich möchte eine UIView in ein Bild konvertieren und in meiner App speichern. Kann mir bitte jemand sagen, wie man einen Screenshot einer Ansicht macht oder sie in ein Bild konvertiert und wie man sie am besten in einer App speichert (keine Kamerarolle)? Hier ist der Code für die Ansicht:

var overView   = UIView(frame: CGRectMake(0, 0, self.view.frame.width/1.3, self.view.frame.height/1.3))
overView.center = CGPointMake(CGRectGetMidX(self.view.bounds),
CGRectGetMidY(self.view.bounds)-self.view.frame.height/16);
overView.backgroundColor = UIColor.whiteColor()
self.view.addSubview(overView)
self.view.bringSubviewToFront(overView)
Sameer Hussain
quelle
Ebenfalls relevant: stackoverflow.com/q/59592933/294884
Fattie

Antworten:

186

Eine Erweiterung UIViewsollte den Trick machen.

extension UIView {

    // Using a function since `var image` might conflict with an existing variable
    // (like on `UIImageView`)
    func asImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }
}

Apple rät davon UIGraphicsBeginImageContextab, iOS 10 mit der Einführung des P3-Farbumfangs zu starten. UIGraphicsBeginImageContextist nur sRGB und 32-Bit. Sie führten die neue UIGraphicsImageRendererAPI ein, die vollständig farbverwaltet und blockbasiert ist, Unterklassen für PDFs und Bilder enthält und die Kontextlebensdauer automatisch verwaltet. Weitere Informationen finden Sie in der WWDC16-Sitzung 205 (das Rendern von Bildern beginnt um 11:50 Uhr).

Verwenden Sie #availableeinen Fallback für frühere Versionen von iOS, um sicherzustellen, dass es auf jedem Gerät funktioniert :

extension UIView {

    // Using a function since `var image` might conflict with an existing variable
    // (like on `UIImageView`)
    func asImage() -> UIImage {
        if #available(iOS 10.0, *) {
            let renderer = UIGraphicsImageRenderer(bounds: bounds)
            return renderer.image { rendererContext in
                layer.render(in: rendererContext.cgContext)
            }
        } else {
            UIGraphicsBeginImageContext(self.frame.size)
            self.layer.render(in:UIGraphicsGetCurrentContext()!)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return UIImage(cgImage: image!.cgImage!)
        }
    }
}
Naveed J.
quelle
9
Dies sollte als die richtige Antwort markiert werden. Alle anderen Optionen führen dazu, dass das gerenderte Bild an Klarheit verliert und pixelig / verschwommen aussieht.
TuplingD
Der einzig richtige Weg! Für Anfänger ist die Verwendung: let image = customView.asImage ()
Fabio
1
Ist es möglich, die UIView mit einem transparenten Hintergrund zu rendern? Meins hat einige abgerundete Ecken.
Ixany
@ixany Das sollte sich schon darum kümmern. Ich habe es gerade mit folgendem auf einem Spielplatz versucht und es hat funktioniert: let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)); view.backgroundColor = .black; view.layer.cornerRadius = 9; view.asImage();
Naveed J.
2
Danke dir! Wenn jemand weiß, wäre ich gespannt, welche Unterschiede es zum Code von hackingwithswift.com/example-code/media/… gibt : return renderer.image {ctx in drawHierarchy (in: bounds, afterScreenUpdates: true)}
Kqtr
63

Sie können die Erweiterung verwenden

extension UIImage {
    convenience init(view: UIView) {
        UIGraphicsBeginImageContext(view.frame.size)
        view.layer.render(in:UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: image!.cgImage!)
    }
}

Hier die schnelle 3/4 Version:

extension UIImage {
    convenience init(view: UIView) {
        UIGraphicsBeginImageContext(view.frame.size)
        view.layer.render(in:UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: image!.cgImage!)
    }
}
Bao Tuan Diep
quelle
5
Es ist mir peinlich, derjenige zu sein, der das fragt, aber wie nenne ich das? Ich habe kein Bild und eine UIView, dass ich ein Bild sein möchte. Der obige Code gibt mir eine UIImage-Erweiterung ... aber was nun?
Dave G
8
let image = UIImage(view: myView)
DoctorBroctor
Funktioniert bei mir nicht, da UIGraphicsGetCurrentContext () Null sein kann und der Code abstürzt.
Juan Carlos Ospina Gonzalez
@JuanCarlosOspinaGonzalez Wenn UIGraphicsGetCurrentContext null zurückgegeben hat, müssen Sie vermutlich UIGraphicsBeginImageContext überprüfen, um herauszufinden, warum dies fehlgeschlagen ist. Ich vermute, dass eine der Dimensionen Ihrer Größe Null oder anderweitig ungültig ist, aber ich habe keine Ahnung, was wirklich dazu führen könnte, dass dies fehlschlägt.
John Stephen
2
Sie sollten auch die Größe des Bildschirms berücksichtigen, damit ich die erste Zeile des Initialisierers durch folgende ersetzen würde: UIGraphicsBeginImageContextWithOptions(view.frame.size, false, UIScreen.main.scale)
iVentis
41

Konvertieren Sie Ihre UIView in ein Bild mit drawViewHierarchyInRect: afterScreenUpdates: Dies ist um ein Vielfaches schneller als renderInContext

Wichtiger Hinweis: Rufen Sie diese Funktion nicht über viewDidLoad oder viewWillAppear auf. Stellen Sie sicher, dass Sie eine Ansicht erfassen, nachdem sie vollständig angezeigt / geladen wurde

Obj C.

     UIGraphicsBeginImageContextWithOptions(myView.bounds.size, myView.opaque, 0.0f);
     [myView drawViewHierarchyInRect:myView.bounds afterScreenUpdates:NO];
     UIImage *snapshotImageFromMyView = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();

     myImageView.image =  snapshotImageFromMyView;

Speichern Sie das bearbeitete Bild Fotoalbum

     UIImageWriteToSavedPhotosAlbum(snapshotImageFromMyView, nil,nil, nil);

Swift 3/4

    UIGraphicsBeginImageContextWithOptions(myView.bounds.size, myView.isOpaque, 0.0)
    myView.drawHierarchy(in: myView.bounds, afterScreenUpdates: false)
    let snapshotImageFromMyView = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    print(snapshotImageFromMyView)
    myImageView.image = snapshotImageFromMyView

Super einfache Verallgemeinerung mit Erweiterung, iOS11, swift3 / 4

extension UIImage{
    convenience init(view: UIView) {

    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.isOpaque, 0.0)
    view.drawHierarchy(in: view.bounds, afterScreenUpdates: false)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    self.init(cgImage: (image?.cgImage)!)

  }
}


Use : 
 //myView is completly loaded/visible , calling this code after only after viewDidAppear is call
 imgVV.image = UIImage.init(view: myView)
 // Simple image object
 let img =  UIImage.init(view: myView)
ViJay Avhad
quelle
3
Keine Arbeit für mich Ich habe einen schwarzen Bildschirm für mein UiImage
Badr Filali
Ja wirklich ?? Können Sie Ihren Code hier einfügen? U verwendet möglicherweise ein falsches UIView-Objekt, um es als UIImage zu konvertieren.
ViJay Avhad
`func convertViewIntoImg () -> Void {imgFakeCard.image = UIImage.init (view: card)}` Mit Ihrer Erweiterung in Swift 3 wird diese Funktion in viewDidLoad
Badr Filali am
1
Vielen Dank, dass Sie Ihren Code veröffentlicht und erwähnt haben, dass Sie viewDidLoad aufgerufen haben. Hier ist, was Sie falsch gemacht haben. Sie erfassen eine Momentaufnahme der Ansicht, bevor sie in den Speicher geladen wird. Bitte versuchen Sie, Code in viewDidAppear aufzurufen, um das Problem sicher zu lösen. Bei Fragen bitte antworten.
ViJay Avhad
Diese Arbeit ist großartig, danke, das Problem kam von dort, wo ich Ihre Nebenstelle angerufen habe
Badr Filali
20

Unter iOS 10:

extension UIImage {
    convenience init(view: UIView) {
        UIGraphicsBeginImageContext(view.frame.size)
        view.layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: (image?.cgImage)!)
    }
}
afrodev
quelle
1
Dies führt zu Abstürzen.
KingPolygon
18

Best Practice ab iOS 10 und Swift 3

Während iOS 9 und frühere Versionen weiterhin unterstützt werden, funktioniert es ab iOS 13, Xcode 11.1, Swift 5.1

extension UIView {

    func asImage() -> UIImage? {
        if #available(iOS 10.0, *) {
            let renderer = UIGraphicsImageRenderer(bounds: bounds)
            return renderer.image { rendererContext in
                layer.render(in: rendererContext.cgContext)
            }
        } else {
            UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0.0)
            defer { UIGraphicsEndImageContext() }
            guard let currentContext = UIGraphicsGetCurrentContext() else {
                return nil
            }
            self.layer.render(in: currentContext)
            return UIGraphicsGetImageFromCurrentImageContext()
        }
    }
}

Ich bin mir nicht sicher, was die Frage bedeutet:

Was ist der beste Weg, um es in einer App zu speichern (keine Kamerarolle)?

Jon Willis
quelle
16
    UIGraphicsBeginImageContext(self.view.bounds.size);        
    self.view.layer.renderInContext(UIGraphicsGetCurrentContext())
    var screenShot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
Vakas
quelle
1
UIGraphicsGetImageFromCurrentImageContext gibt UIImage zurück. Keine Notwendigkeit, es zu UIImage
Leo Dabus
Dies macht einen Screenshot der gesamten Ansicht, ja? Ich möchte nur eine UIView, dh eine Übersicht in meinem Code, die eine Unteransicht von self.view ist, in ein Bild konvertieren. Nicht die ganze Ansicht!
Sameer Hussain
@ Vakas, als ich versuchte, image.it Anzeige zu klein zu drucken. Was ist Lösung für dieses
Krutarth Patel
6
Das Screenshot-Bild hat keine gute Qualität. Was soll ich tun?
Neela
13

Zum Beispiel, wenn ich eine Ansicht der Größe habe: 50 50 bei 100.100. Ich kann Folgendes verwenden, um einen Screenshot zu machen:

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(100, 100), false, 0);
    self.view.drawViewHierarchyInRect(CGRectMake(-50,-5-,view.bounds.size.width,view.bounds.size.height), afterScreenUpdates: true)
    var image:UIImage = UIGraphicsGetImageFromCurrentImageContext();
Sameer Hussain
quelle
In der Zeile self.view gibt es einen Fehler im Parameter. Ich denke, es sollte -5 sein, nicht -5-
Krutarth Patel
@sameer Ich habe eine Frage. Wenn ich dieses Bild
drucke,
7

Meiner Meinung nach ist der Ansatz mit dem Initialisierer nicht so gut, weil er zwei Bilder erzeugt.

Ich bevorzuge das:

extension UIView {
    var snapshot: UIImage? {
        UIGraphicsBeginImageContext(self.frame.size)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }
        layer.render(in: context)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}
Tino
quelle
Sie sollten die Eigenschaft etwas anderes als Bild nennen. Dies kann Unterklassen stören, deren Eigenschaften als Bild bezeichnet werden, z. B. UIImageView.
Hobbes the Tige
Befolgte den Vorschlag von @HobbestheTige und benannte das Anwesen um
Tino
6

Swift 4.2, iOS 10

extension UIView {

    // If Swift version is lower than 4.2, 
    // You should change the name. (ex. var renderedImage: UIImage?)

    var image: UIImage? {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in layer.render(in: rendererContext.cgContext) }
    }
}

Stichprobe

let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view.backgroundColor = .blue

let view2 = UIView(frame: CGRect(x: 10, y: 10, width: 20, height: 20))
view2.backgroundColor = .red
view.addSubview(view2)

let imageView = UIImageView(image: view.image)

Geben Sie hier die Bildbeschreibung ein

Den
quelle
Ich wollte nur darauf hinweisen, dass dies einen anderen Namen haben muss, wenn Sie UIImageViews in Ihrem Projekt verwenden, andernfalls wird .image schreibgeschützt. Nennen Sie es vielleicht "screenCapture" anstelle von "image".
Chris
@ Chris Ja, du hast recht. Sie sollten einen Namen ändern, wenn die Swift-Version niedriger als 4.2 ist. Vielen Dank, dass Sie auf den Fehler hingewiesen haben.
Den
6

Dies funktioniert bei mir für Xcode 9 / Swift 3.2 / Swift 4 und Xcode 8 / Swift 3

 if #available(iOS 10.0, *) {

     // for Xcode 9/Swift 3.2/Swift 4 -Paul Hudson's code
     let renderer = UIGraphicsImageRenderer(size: view!.bounds.size)
     let capturedImage = renderer.image { 
         (ctx) in
         view!.drawHierarchy(in: view!.bounds, afterScreenUpdates: true)
     }
     return capturedImage

 } else {

     // for Xcode 8/Swift 3
     UIGraphicsBeginImageContextWithOptions((view!.bounds.size), view!.isOpaque, 0.0)
     view!.drawHierarchy(in: view!.bounds, afterScreenUpdates: false)
     let capturedImage = UIGraphicsGetImageFromCurrentImageContext()
     UIGraphicsEndImageContext()
     return capturedImage!
 }

So verwenden Sie es in einer Funktion:

fileprivate func captureUIImageFromUIView(_ view:UIView?) -> UIImage {

     guard (view != nil) else{

        // if the view is nil (it's happened to me) return an alternative image
        let errorImage = UIImage(named: "Error Image")
        return errorImage
     }

     // if the view is all good then convert the image inside the view to a uiimage
     if #available(iOS 10.0, *) {

         let renderer = UIGraphicsImageRenderer(size: view!.bounds.size)
         let capturedImage = renderer.image { 
             (ctx) in
             view!.drawHierarchy(in: view!.bounds, afterScreenUpdates: true)
         }
         return capturedImage

     } else {

         UIGraphicsBeginImageContextWithOptions((view!.bounds.size), view!.isOpaque, 0.0)
         view!.drawHierarchy(in: view!.bounds, afterScreenUpdates: false)
         let capturedImage = UIGraphicsGetImageFromCurrentImageContext()
         UIGraphicsEndImageContext()
         return capturedImage!
     }
}

So machen Sie etwas mit dem von der Funktion zurückgegebenen Bild:

@IBOutlet weak fileprivate var myCustomView: UIView!
var myPic: UIImage?

let myImageView = UIImageView()

@IBAction fileprivate func saveImageButtonTapped(_ sender: UIButton) {

   myPic = captureUIImageFromUIView(myCustomView)

   // display the pic inside a UIImageView
   myImageView.image = myPic!
}

Ich habe die Antwort Xcode 9 / Swift 3.2 / Swift 4 von Paul Hudson erhalten , der uiview in uiimage konvertiert

Ich habe den Xcode 8 / Swift 3 vor langer Zeit von irgendwo auf SO bekommen und habe vergessen, wo :(

Lance Samaria
quelle
Auch wo wird das Bild angezeigt und / oder gespeichert?
Famic Tech
@FamicTech Sobald das Bild erstellt ist, liegt es an der Jugend, zu entscheiden, was damit gemacht werden soll. In dem Beispiel aus meinem Code habe ich gerade die UIView in ein UIImage mit dem Namen "myPic" konvertiert, aber mit 'myPic' nichts gemacht. Der nächste mögliche Schritt besteht darin, 'myPic' in einem UIImageVIew wie folgt anzuzeigen: myImageVIew.image = myPic. Wenn Sie eine collectionView verwenden und Bilder darin anzeigen möchten, erstellen Sie in jeder Zelle eine UIImageVIew und zeigen dann das Bild (myPic) in der UIImageVIew über indexPath.item aus der Datenquelle an, z. B.: MyImageView.image = dataSource [indexPath .item] .myPic
Lance Samaria
@FamicTech Du machst einen kleinen Fehler. Dies hat nichts mit einer collectionVIew zu tun. Sie haben 2 verschiedene Klassentypen: UIImage und UIView. Beide können verwendet werden, um jedes Bild anzuzeigen, aber beide tun dies auf unterschiedliche Weise. In iOS ist so ziemlich alles eine Unterklasse eines UIView, aber ein UIImage kann nur Bilder anzeigen (2 verschiedene Dinge). Diese Funktion nimmt das UIVIew und konvertiert es in ein UIImage. Ein einfacher zB. Wenn Sie 4.0 (ein Double) in 4 (ein Int) konvertieren möchten, setzen Sie es in Int (4.0) um. Das Ergebnis ist 4. Damit konvertieren Sie das Bild in der UIVIew in ein UIImage. Verstehen?
Lance Samaria
Ich versuche, den Benutzer zu meinem Collection View Controller zu bringen und eine Taste zu drücken, die die aktuelle Ansicht, die zufällig eine Collection View 10x10 ist, aufnimmt und ein Bild des gesamten 10x10-Rasters erstellt (bitte beachten Sie, dass das gesamte Bild angezeigt wird) Gitter ist in der Ansicht nicht vollständig sichtbar). Löst Ihr obiger Code diesen Anwendungsfall?
Famic Tech
Die Schaltfläche befindet sich im Navigationscontroller. Der Benutzer würde darauf klicken und es sollte die unter dem Navigationscontroller angezeigte Sammlungsansicht übernehmen und ein Bild der Sammlungsansicht (ein PDF würde auch funktionieren) mit allen Informationen in den Zellen in der Sammlungsansicht erstellen.
Famic Tech
5
var snapshot = overView.snapshotViewAfterScreenUpdates(false)

oder in Ziel-c

UIView* snapshot = [overView snapshotViewAfterScreenUpdates:NO];
Yedidya Reiss
quelle
Ist imageView dasselbe wie image? Wenn ja, wie speichere ich es in meiner App?
Sameer Hussain
4

Sie können es einfach verwenden, indem Sie die Erweiterung wie folgt verwenden

// Take a snapshot from a view (just one view)
let viewSnapshot = myView.snapshot

// Take a screenshot (with every views in screen)
let screenSnapshot = UIApplication.shared.snapshot

// Take a snapshot from UIImage initialization
UIImage(view: self.view)

Wenn Sie diese Erweiterungsmethode / -variablen verwenden möchten, implementieren Sie dies

  1. UIImage-Erweiterung

    extension UIImage {
        convenience init(view: UIView) {
            if let cgImage = view.snapshot?.cgImage {
                self.init(cgImage: cgImage)
            } else {
                self.init()
            }
        }
    }
  2. UIView-Erweiterung

    extension UIView {
    
        var snapshot: UIImage? {
            UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0.0)
            if UIGraphicsGetCurrentContext() != nil {
                drawHierarchy(in: bounds, afterScreenUpdates: true)
                let screenshot = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return screenshot
            }
            return nil
        }
    }
  3. UIApplication-Erweiterung

    extension UIApplication {
    
        var snapshot: UIImage? {
            return keyWindow?.rootViewController?.view.snapshot
        }
    }
Khemmachart Chutapetch
quelle
Ich hatte Ansicht mit Unteransichten zPositions manipuliert, und andere Antworten gaben mir nicht die richtigen Ebenenpositionen, danke.
Ashkan Ghodrat
3

oder iOS 10+ können Sie den neuen UIGraphicsImageRenderer + die empfohlene drawHierarchy verwenden, die in einigen Situationen viel schneller sein kann als layer.renderInContext

extension UIView {
    func asImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(size: self.bounds.size)
        return renderer.image { _ in
            self.drawHierarchy(in: CGRect(x: 0, y: 0, width: bounds.size.width, height: bounds.size.height), afterScreenUpdates: false)
        }
    }
}
Морт
quelle
3

Danke @Bao Tuan Diep! Ich möchte eine Ergänzung hinzufügen.

Wenn Sie den Code verwenden:

yourView.layer.render(in:UIGraphicsGetCurrentContext()!)

Sie müssen beachten, dass:

 - If you had used `autoLayout` or `Masonry` in `yourView` (that you want to convert) .
 - If you did not add `yourView` to another view which means that `yourView` was not used as a subview but just an object.

Dann müssen Sie verwenden :

[yourView setNeedsLayout];
[yourView layoutIfNeeded];

yourViewvorher zu aktualisieren yourView.layer.render(in:UIGraphicsGetCurrentContext()!).

Andernfalls erhalten Sie möglicherweise ein Bildobjekt, das keine Elemente enthält

guozqzzu
quelle
Danke dafür. Hat mir sehr geholfen !!
Maksim Kniazev
2

Swift 4.2

import Foundation
import UIKit  

extension UIImage {

    convenience init(view: UIView) {

        UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.isOpaque, 0.0)
        view.drawHierarchy(in: view.bounds, afterScreenUpdates: false)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: (image?.cgImage)!)

    } 
}

mit:

let img = UIImage.init (Ansicht: self.holderView)

reza_khalafi
quelle
1

Implementierung in Swift 3 :

Fügen Sie den folgenden Code außerhalb des Klassenbereichs hinzu.

extension UIImage {
    convenience init(_ view: UIView) {
        UIGraphicsBeginImageContext(view.frame.size)
        view.layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: (image?.cgImage)!)
    }
}

Verwendung :

let image = UIImage( Your_View_Outlet )
Roy
quelle
Fehler erhalten "Zeichnen einer Ansicht (0x1040a6970, UIView), die nicht mindestens einmal gerendert wurde, erfordert"
kishu mewara
0

Ich habe die Methode von @Naveed J. wie folgt implementiert und sie hat wie ein Zauber funktioniert.

Hier war seine Ausdehnung:

extension UIView {

    // Using a function since `var image` might conflict with an existing variable
    // (like on `UIImageView`)
    func asImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }
}

Hier ist, wie ich es implementiert habe.

//create an image from yourView to display
//determine the frame of the view/imageimage
let screen = self.superview!.bounds
let width = screen.width / 4 //make image 1/4 width of screen
let height = width
let frame = CGRect(x: 0, y: 0, width: width, height: height)
let x = (screen.size.width - frame.size.width) * 0.5
let y = (screen.size.height - frame.size.height) * 0.5
let mainFrame = CGRect(x: x, y: y, width: frame.size.width, height: frame.size.height)

let yourView = YourView() //instantiate yourView
yourView.frame = mainFrame //give it the frame
yourView.setNeedsDisplay() //tell it to display (I am not 100% sure this is needed)

let characterViewImage = yourView.asImage()
Jacob F. Davis C-CISO
quelle
0

Initializer mit dem neuen UIGraphicsImageRenderer seit iOS 10:

extension UIImage{
    convenience init(view: UIView) {

    let renderer = UIGraphicsImageRenderer(size: self.bounds.size)
    let canvas = CGRect(x: 0, y: 0, width: bounds.size.width, height: bounds.size.height)
    let image = renderer.image { _ in
        self.drawHierarchy(in: canvas, afterScreenUpdates: false)
    }
    self.init(cgImage: (image?.cgImage)!)
  }
}
Frédéric Adda
quelle
0

arbeite gut mit mir!

Swift4

 extension UIView {

    func toImage() -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0.0)
        self.drawHierarchy(in: self.bounds, afterScreenUpdates: false)
        let snapshotImageFromMyView = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return snapshotImageFromMyView!
    }

    }
Faris
quelle
return snapshotImageFromMyView!Thread 1: Schwerwiegender Fehler: Beim Auspacken eines optionalen Werts wurde unerwartet Null gefunden
Takasur
0

Die Ansicht enthält eine unscharfe Unteransicht (z. B. die Instanz UIVisualEffectView ), nur drawViewHierarchyInRect: afterScreenUpdates funktioniert.

Die Antwort von @ViJay Avhad ist für diesen Fall richtig.

Rafalkitta
quelle
-1
please try below code.
-(UIImage *)getMainImageFromContext
{
UIGraphicsBeginImageContextWithOptions(viewBG.bounds.size, viewBG.opaque, 0.0);
[viewBG.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
herry.master
quelle