Cara mengonversi UIView menjadi gambar

99

Saya ingin mengonversi UIView menjadi gambar dan menyimpannya di aplikasi saya. Bisakah seseorang memberi tahu saya cara mengambil tangkapan layar dari suatu tampilan atau mengonversinya menjadi gambar dan apa cara terbaik untuk menyimpannya dalam aplikasi (Bukan rol kamera)? Ini kode untuk tampilan tersebut:

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
sumber

Jawaban:

199

Perpanjangan UIViewharus melakukan trik.

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 melarang penggunaan UIGraphicsBeginImageContextmulai iOS 10 dengan pengenalan gamut warna P3. UIGraphicsBeginImageContexthanya sRGB dan 32-bit. Mereka memperkenalkan UIGraphicsImageRendererAPI baru yang sepenuhnya dikelola dengan warna, berbasis blok, memiliki subkelas untuk PDF dan gambar, dan secara otomatis mengelola seumur hidup konteks. Lihat WWDC16 sesi 205 untuk lebih jelasnya (rendering gambar dimulai sekitar tanda 11:50)

Untuk memastikannya berfungsi di setiap perangkat, gunakan #availabledengan fallback ke versi iOS yang lebih lama:

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.
sumber
9
Ini harus ditandai sebagai jawaban yang benar. Semua opsi lain akan menyebabkan gambar yang dirender kehilangan kejelasan dan terlihat pecah / buram.
TuplingD
Satu-satunya cara yang benar! Untuk pemula penggunaannya adalah: biarkan image = customView.asImage ()
Fabio
1
Apakah mungkin untuk membuat UIView dengan latar belakang transparan? Punyaku memiliki beberapa sudut membulat.
ixany
@ixany Ini seharusnya sudah membereskannya. Saya baru saja mencobanya dengan yang berikut di Playground dan berhasil: 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
Terima kasih! Jika ada yang tahu, saya ingin tahu apa perbedaannya dengan kode dari hackingwithswift.com/example-code/media/… : return renderer.image {ctx in drawHierarchy (in: bounds, afterScreenUpdates: true)}
Kqtr
64

Anda dapat menggunakan ekstensi

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

Berikut versi swift 3/4:

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
sumber
5
Saya malu menjadi orang yang menanyakan hal ini, tetapi bagaimana saya menyebutnya? Saya tidak memiliki gambar dan UIView yang saya ingin gambar. Kode di atas memberi saya ekstensi UIImage ... tapi sekarang bagaimana?
Dave G
8
let image = UIImage(view: myView)
doctorBroctor
Tidak berfungsi untuk saya karena UIGraphicsGetCurrentContext () bisa nihil dan kode macet.
Juan Carlos Ospina Gonzalez
@JuanCarlosOspinaGonzalez Jika UIGraphicsGetCurrentContext kembali nihil maka saya menduga Anda perlu memeriksa UIGraphicsBeginImageContext untuk mencari tahu mengapa gagal. Dugaan saya adalah bahwa salah satu dimensi ukuran Anda adalah nol atau tidak valid, tetapi saya tidak tahu benar apa yang dapat menyebabkannya gagal.
John Stephen
2
Anda juga harus mengingat skala layar, jadi saya akan mengganti baris pertama penginisialisasi dengan ini: UIGraphicsBeginImageContextWithOptions(view.frame.size, false, UIScreen.main.scale)
iVentis
41

Ubah UIView Anda menjadi gambar dengan drawViewHierarchyInRect: afterScreenUpdates: yang jauh lebih cepat daripada renderInContext

Catatan penting: jangan panggil fungsi ini dari viewDidLoad atau viewWillAppear , pastikan Anda menangkap tampilan setelah itu ditampilkan / dimuat sepenuhnya

Obj C

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

     myImageView.image =  snapshotImageFromMyView;

Simpan album foto gambar yang diedit

     UIImageWriteToSavedPhotosAlbum(snapshotImageFromMyView, nil,nil, nil);

Cepat 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

Generalisasi super mudah dengan ekstensi, 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
sumber
3
Tidak bekerja untuk saya Saya mendapat layar hitam untuk Gambar saya
Badr Filali
Betulkah ?? Dapatkah Anda menempelkan kode Anda di sini .. Anda mungkin menggunakan objek UIView yang salah untuk diubah sebagai UIImage.
ViJay Avhad
`func convertViewIntoImg () -> Void {imgFakeCard.image = UIImage.init (view: card)}` Dengan ekstensi Anda di swift 3, fungsi ini dipanggil di viewDidLoad
Badr Filali
1
Terima kasih telah memposting kode Anda dan menyebutkan bahwa Anda telah memanggil di viewDidLoad. Inilah yang salah Anda. Anda menangkap potret tampilan sebelum dimuat ke dalam memori. Silakan coba panggil kode di viewDidAppear, itu pasti akan menyelesaikan masalah. Ada pertanyaan silahkan balas.
ViJay Avhad
Kerja bagus, terima kasih, masalahnya berasal dari tempat saya menelepon ekstensi Anda
Badr Filali
20

Di 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
sumber
1
ini menyebabkan crash.
KingPolygon
18

Praktik terbaik untuk iOS 10 dan Swift 3

sementara masih mendukung iOS 9 dan sebelumnya masih berfungsi pada 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()
        }
    }
}

Saya tidak yakin apa maksud pertanyaan itu dengan:

apa cara terbaik untuk menyimpannya dalam aplikasi (Bukan rol kamera)?

Jon Willis
sumber
17
    UIGraphicsBeginImageContext(self.view.bounds.size);        
    self.view.layer.renderInContext(UIGraphicsGetCurrentContext())
    var screenShot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
Vakas
sumber
1
UIGraphicsGetImageFromCurrentImageContext mengembalikan UIImage. Tidak perlu
mengirimkannya
Ini mengambil tangkapan layar dari seluruh tampilan ya? Saya hanya ingin mengubah ikhtisar UIView yaitu dalam kode saya yang merupakan subview dari self.view ke gambar. Bukan seluruh tampilan!
Sameer Hussain
@Vaka ketika saya mencoba mencetak gambar. Layarnya terlalu kecil. Apa solusi untuk ini
Krutarth Patel
6
Gambar screenshot tidak memiliki kualitas yang baik, apa yang harus saya lakukan?
Neela
13

Misalnya jika saya memiliki view of size: 50 50 pada 100.100. Saya dapat menggunakan yang berikut ini untuk mengambil tangkapan layar:

    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
sumber
di self.view line ada kesalahan dalam parameter. saya pikir seharusnya -5 bukan
-5-
@sameer saya punya satu pertanyaan. ketika saya mencetak gambar ini terlalu kecil
Krutarth Patel
7

Menurut saya, pendekatan dengan penginisialisasi tidak terlalu bagus karena menghasilkan dua gambar.

Saya lebih memilih ini:

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
sumber
Anda harus menyebut properti itu sesuatu selain gambar. Ini dapat mengganggu subclass yang memiliki properti yang disebut image, seperti UIImageView.
Hobbes the Tige
Mengikuti saran @HobbestheTige dan mengganti nama properti
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) }
    }
}

Sampel

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)

masukkan deskripsi gambar di sini

Sarang
sumber
Hanya ingin menunjukkan bahwa ini perlu diberi nama lain jika Anda menggunakan UIImageViews dalam proyek Anda, jika tidak .image menjadi hanya baca. Mungkin menyebutnya 'screenCapture' bukan 'image'.
Chris
@ Chris Ya, Anda benar. Anda harus mengubah nama jika versi Swift lebih rendah dari 4.2. Terima kasih telah menunjukkan kesalahannya.
Den
6

Ini berfungsi untuk saya untuk Xcode 9 / Swift 3.2 / Swift 4 dan 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!
 }

Berikut cara menggunakannya di dalam fungsi:

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!
     }
}

Berikut cara melakukan sesuatu dengan gambar yang dikembalikan dari fungsi:

@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!
}

Saya mendapatkan Xcode 9 / Swift 3.2 / Swift 4 dari Paul Hudson, ubah uiview ke uiimage

Saya mendapatkan Xcode 8 / Swift 3 dari suatu tempat di SO sejak lama dan saya lupa di mana :(

Lance Samaria
sumber
Juga di mana gambar itu ditampilkan dan / atau disimpan?
Famic Tech
@FamicTech setelah gambar dibuat, terserah kaum muda untuk memutuskan apa yang harus dilakukan dengannya. Dalam contoh dari kode saya, saya baru saja mengubah UIView menjadi gambar UII bernama "myPic" tetapi saya tidak melakukan apa pun dengan 'myPic'. Langkah selanjutnya yang mungkin adalah menampilkan 'myPic' di dalam UIImageVIew seperti ini: myImageVIew.image = myPic. Jika Anda menggunakan collectionView dan ingin menampilkan gambar di dalamnya, buat UIImageVIew di setiap sel, lalu tampilkan gambar (myPic) di dalam UIImageVIew melalui indexPath.item dari sumber data misalnya: myImageView.image = dataSource [indexPath .item] .myPic
Lance Samaria
@FamicTech Anda membuat sedikit kesalahan. Ini tidak ada hubungannya dengan collectionVIew. Anda memiliki 2 jenis kelas yang berbeda: UIImage dan UIView. Keduanya dapat digunakan untuk menampilkan gambar apa pun, tetapi keduanya melakukannya dengan cara yang berbeda. Hampir semua yang ada di iOS adalah subclass dari UIView tetapi UIImage hanya dapat menampilkan gambar (2 hal berbeda). Fungsi ini adalah mengambil UIVIew dan mengubahnya menjadi UIImage. Contoh yang lebih mudah. Jika Anda ingin mengubah 4.0 (a Double) menjadi 4 (sebuah Int) Anda melemparkannya Int (4.0) hasilnya adalah 4. Tetapi dengan ini Anda mengubah gambar di dalam UIVIew menjadi UIImage. Memahami?
Lance Samaria
apa yang saya coba lakukan adalah meminta pengguna datang ke Pengontrol Tampilan Koleksi saya dan menekan tombol yang akan menampilkan tampilan saat ini, yang kebetulan adalah Tampilan Koleksi 10x10 dan membuat gambar dari seluruh kisi 10x10 (harap diperhatikan bahwa keseluruhan grid tidak sepenuhnya terlihat dalam tampilan). Apakah kode Anda di atas menyelesaikan kasus penggunaan tersebut?
Famic Tech
Tombolnya ada di Pengontrol Navigasi. Pengguna akan mengkliknya dan 'harus' mengambil Tampilan Koleksi yang ditampilkan di bawah pengontrol navigasi dan membuat Gambar Tampilan Koleksi (PDF juga akan berfungsi) dengan semua informasi di Sel dalam Tampilan Koleksi.
Famic Tech
5
var snapshot = overView.snapshotViewAfterScreenUpdates(false)

atau secara objektif-c

UIView* snapshot = [overView snapshotViewAfterScreenUpdates:NO];
Yedidya Reiss
sumber
Apakah imageView sama dengan gambar? Jika demikian, bagaimana cara menyimpannya di aplikasi saya?
Sameer Hussain
4

Anda dapat menggunakannya dengan mudah dengan menggunakan ekstensi seperti ini

// 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)

Jika Anda ingin menggunakan metode / variabel ekstensi tersebut, terapkan ini

  1. Ekstensi UIImage

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

    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. Ekstensi UIApplication

    extension UIApplication {
    
        var snapshot: UIImage? {
            return keyWindow?.rootViewController?.view.snapshot
        }
    }
    
Khemmachart Chutapetch
sumber
Saya melihat dengan subviews zPosisi dimanipulasi, dan jawaban lain tidak memberi saya posisi lapisan yang benar, terima kasih.
Ashkan Ghodrat
3

atau iOS 10+ Anda dapat menggunakan UIGraphicsImageRenderer + drawHierarchy baru yang direkomendasikan, yang dalam beberapa situasi bisa jauh lebih cepat daripada 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)
        }
    }
}
Морт
sumber
3

Terima kasih @Bao Tuan Diep! Saya ingin menambahkan suplemen.

Saat Anda menggunakan kode:

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

Anda harus memperhatikan bahwa:

 - 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.

Kemudian, Anda harus menggunakan :

[yourView setNeedsLayout];
[yourView layoutIfNeeded];

untuk memperbarui yourViewsebelumnya yourView.layer.render(in:UIGraphicsGetCurrentContext()!).

Jika tidak, Anda mungkin mendapatkan objek gambar yang tidak mengandung elemen

guozqzzu
sumber
Terima kasih untuk ini. Banyak membantu !!
Maksim Kniazev
2

Swift 4.2.0

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)!)

    } 
}

menggunakan:

biarkan img = UIImage.init (view: self.holderView)

reza_khalafi
sumber
1

Implementasi di Swift 3 :

Tambahkan kode di bawah ini, di luar cakupan kelas.

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

Penggunaan:

let image = UIImage( Your_View_Outlet )
roy
sumber
mendapatkan kesalahan "Menggambar tampilan (0x1040a6970, UIView) yang belum dirender setidaknya sekali membutuhkan"
kishu mewara
0

Saya menerapkan @Naveed J. seperti ini, dan itu bekerja dengan sangat baik.

Inilah perpanjangannya:

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)
        }
    }
}

Inilah cara saya menerapkannya.

//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
sumber
0

Penginisialisasi dengan UIGraphicsImageRenderer baru tersedia sejak 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
sumber
0

bekerja dengan baik dengan saya!

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
sumber
return snapshotImageFromMyView!Utas 1: Kesalahan fatal: Tidak terduga ditemukan nol saat membuka bungkus Nilai opsional
Takasur
0

Untuk tampilan berisi subview buram (misalnya, instance UIVisualEffectView ), hanya drawViewHierarchyInRect: afterScreenUpdates yang berfungsi.

Jawaban @ViJay Avhad benar untuk kasus ini.

rafalkitta
sumber
0

Penggunaan UIGraphicsImageRenderer tidak berfungsi saat tampilan berisi sub-tampilan Scene Kit, Metal atau Sprite Kit. Dalam kasus ini, gunakan

let renderer = UIGraphicsImageRenderer(size: view.bounds.size)
let image = renderer.image { ctx in
    view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
}
johnnyMac
sumber
-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
sumber