Làm thế nào để chuyển đổi một UIView thành một hình ảnh


94

Tôi muốn chuyển đổi UIView thành hình ảnh và lưu nó trong ứng dụng của mình. Ai đó có thể vui lòng cho tôi biết cách chụp ảnh màn hình của một chế độ xem hoặc chuyển đổi nó thành một hình ảnh và cách tốt nhất để lưu nó trong một ứng dụng (Không phải thư viện ảnh) là gì? Đây là mã cho chế độ xem:

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)

Câu trả lời:


189

Một phần mở rộng trên UIViewsẽ thực hiện thủ thuật.

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 không khuyến khích sử dụng UIGraphicsBeginImageContextbắt đầu từ iOS 10 với sự ra đời của gam màu P3. UIGraphicsBeginImageContextchỉ là sRGB và 32-bit. Họ đã giới thiệu UIGraphicsImageRendererAPI mới được quản lý hoàn toàn bằng màu, dựa trên khối, có các lớp con cho PDF và hình ảnh, đồng thời tự động quản lý thời gian tồn tại của ngữ cảnh. Hãy xem WWDC16 phiên 205 để biết thêm chi tiết (kết xuất hình ảnh bắt đầu vào khoảng 11:50)

Để đảm bảo rằng nó hoạt động trên mọi thiết bị, hãy sử dụng #availabledự phòng cho các phiên bản iOS cũ hơn:

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

9
Đây phải được đánh dấu là câu trả lời đúng. Tất cả các tùy chọn khác sẽ làm cho hình ảnh hiển thị mất đi độ rõ nét và trông bị pixel / mờ.
TuplingD

Cách duy nhất đúng! Đối với người mới bắt đầu sử dụng là: let image = customView.asImage ()
Fabio

1
Có thể kết xuất UIView với nền trong suốt không? Của tôi có một số góc tròn.
ixany

@ixany Cái này chắc đã lo rồi. Tôi chỉ cố gắng những điều sau đây một sân chơi và nó làm việc: 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
Cảm ơn bạn! Nếu ai đó biết, tôi rất tò mò muốn biết có sự khác biệt nào với mã từ hackingwithswift.com/example-code/media/… : return renderer.image {ctx trong drawHierarchy (in: bounds, afterScreenUpdates: true)}
Kqtr 21/02/19

63

bạn có thể sử dụng tiện ích mở rộng

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

Đây là phiên bản 3/4 nhanh chóng:

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

5
Tôi xấu hổ khi là người hỏi điều này, nhưng làm thế nào để tôi gọi đây? Tôi không có hình ảnh và UIView mà tôi muốn trở thành hình ảnh. Đoạn mã trên cho tôi tiện ích mở rộng UIImage ... nhưng bây giờ thì sao?
Dave G

8
let image = UIImage(view: myView)
doctorBroctor,

Không hoạt động với tôi vì UIGraphicsGetCurrentContext () có thể là con số không và mã bị treo.
Juan Carlos Ospina Gonzalez

@JuanCarlosOspinaGonzalez Nếu UIGraphicsGetCurrentContext trả về con số không thì tôi nghi ngờ bạn cần kiểm tra UIGraphicsBeginImageContext để tìm ra lý do tại sao nó không thành công. Tôi đoán là một trong các kích thước có kích thước của bạn bằng 0 hoặc không hợp lệ, nhưng tôi không biết thực sự điều gì có thể khiến điều đó bị lỗi.
John Stephen

2
bạn cũng nên lưu ý quy mô của màn hình, vì vậy tôi sẽ thay thế dòng đầu tiên của initializer với điều này: UIGraphicsBeginImageContextWithOptions(view.frame.size, false, UIScreen.main.scale)
iVentis

41

Chuyển đổi UIView của bạn để hình ảnh bằng cách drawViewHierarchyInRect: afterScreenUpdates: đó là nhanh hơn so với renderInContext nhiều lần

Lưu ý quan trọng: không gọi hàm này từ viewDidLoad hoặc viewWillAppear , hãy đảm bảo rằng bạn đang chụp một chế độ xem sau khi nó được hiển thị / tải đầy đủ

Mục tiêu C

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

     myImageView.image =  snapshotImageFromMyView;

Lưu hình ảnh đã chỉnh sửa Album ảnh

     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

Tổng quát hóa siêu dễ dàng với tiện ích mở rộng, 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)

3
Không làm việc cho tôi, tôi có một blackscreen cho UIImage của tôi
Badr Filali

Có thật không ?? Bạn có thể dán mã của mình vào đây .. Bạn có thể đang sử dụng sai đối tượng UIView để được chuyển đổi thành UIImage.
ViJay Avhad

'Func convertViewIntoImg () -> Void {imgFakeCard.image = UIImage.init (xem: thẻ)} `Với phần mở rộng của bạn trong nhanh chóng 3 chức năng này được gọi là trong viewDidLoad
Badr Filali

1
Cảm ơn bạn đã đăng mã của bạn và nói rằng bạn đã gọi trong viewDidLoad. Đây là những gì bạn đã làm sai. Bạn đang chụp một ảnh chụp nhanh của chế độ xem trước khi nó được tải vào bộ nhớ. Vui lòng thử gọi mã trong viewDidAppear, điều đó chắc chắn sẽ giải quyết được vấn đề. Bất kỳ câu hỏi xin vui lòng trả lời.
ViJay Avhad

Đó là cầu thủ vĩ đại làm việc nhờ, vấn đề đến từ nơi tôi gọi là phần mở rộng của bạn
Badr Filali

20

Trên 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)!)
    }
}

1
điều này dẫn đến sự cố.
KingPolygon 20/09/17

18

Phương pháp hay nhất kể từ iOS 10 và Swift 3

trong khi vẫn hỗ trợ iOS 9 trở về trước vẫn hoạt động như 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()
        }
    }
}

Tôi không chắc câu hỏi có nghĩa là gì bởi:

cách tốt nhất để lưu nó trong một ứng dụng (Không phải thư viện ảnh) là gì?


17
    UIGraphicsBeginImageContext(self.view.bounds.size);        
    self.view.layer.renderInContext(UIGraphicsGetCurrentContext())
    var screenShot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


1
UIGraphicsGetImageFromCurrentImageContext trả về UIImage. Không cần phải bỏ nó vào UIImage
Leo Dabus

Điều này chụp ảnh màn hình của toàn bộ chế độ xem đúng không? Tôi chỉ muốn chuyển đổi một UIView tức là tổng quan trong mã của tôi, đó là subview của self.view thành một hình ảnh. Không phải toàn bộ xem!
Sameer Hussain

@Vakas khi tôi đã cố gắng để in image.it hiển thị quá small.what là giải pháp cho điều này
Krutarth Patel

6
Hình ảnh chụp màn hình không có chất lượng tốt, tôi phải làm gì?
Neela,

13

Ví dụ: nếu tôi có chế độ xem kích thước: 50 50 ở 100,100. Tôi có thể sử dụng cách sau để chụp ảnh màn hình:

    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();

phù self.view có sai lầm trong parameter.i nghĩ rằng nó phải -5 không -5-
Krutarth Patel

@sameer tôi có một question.when i in hình ảnh này còn quá nhỏ
Krutarth Patel

7

Theo ý kiến ​​của tôi, cách tiếp cận với trình khởi tạo không phải là tuyệt vời vì nó tạo ra hai hình ảnh.

Tôi thích điều này:

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

Bạn nên gọi thuộc tính là một cái gì đó khác với hình ảnh. Điều này có thể can thiệp vào các lớp con có thuộc tính được gọi là hình ảnh, chẳng hạn như UIImageView.
Hobbes the Tige

Đã làm theo đề xuất của @HobbestheTige và đổi tên tài sản
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) }
    }
}

Mẫu vật

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)

nhập mô tả hình ảnh ở đây


Chỉ muốn chỉ ra rằng điều này cần phải được đặt tên khác nếu bạn đang sử dụng bất kỳ UIImageViews nào trong dự án của mình, nếu không thì .image trở thành chỉ đọc. Có thể gọi nó là 'ScreenCapture' thay vì 'image'.
Chris

@Chris Vâng, bạn nói đúng. Bạn nên đổi tên nếu phiên bản Swift thấp hơn 4.2. Cảm ơn bạn đã chỉ ra sai lầm.
Den

6

Điều này phù hợp với tôi cho Xcode 9 / Swift 3.2 / Swift 4Xcode 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!
 }

Đây là cách sử dụng nó bên trong một hàm:

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

Đây là cách thực hiện điều gì đó với hình ảnh được trả về từ hàm:

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

Tôi đã nhận được câu trả lời Xcode 9 / Swift 3.2 / Swift 4 từ Paul Hudson để chuyển đổi uiview thành uiimage

Tôi đã nhận được Xcode 8 / Swift 3 từ một nơi nào đó trên SO một thời gian dài trước đây và tôi đã quên ở đâu :(


Ngoài ra, hình ảnh được hiển thị và / hoặc lưu ở đâu?
Famic Tech

@FamicTech khi hình ảnh được tạo ra, thanh niên sẽ quyết định làm gì với nó. Trong ví dụ từ mã của tôi, tôi vừa chuyển đổi UIView thành UIImage có tên "myPic" nhưng tôi không làm gì với 'myPic'. Bước tiếp theo có thể thực hiện là hiển thị 'myPic' bên trong một UIImageVIew như sau: myImageVIew.image = myPic. Nếu bạn đang sử dụng collectionView và bạn muốn hiển thị hình ảnh trong đó thì bạn tạo một UIImageVIew trong mỗi ô và sau đó hiển thị hình ảnh (myPic) bên trong UIImageVIew thông qua indexPath.item từ nguồn dữ liệu, ví dụ: myImageView.image = dataSource [indexPath .item] .myPic
Lance Samaria

@FamicTech Bạn đang mắc một sai lầm nhỏ. Điều này không liên quan gì đến một bộ sưu tập. Bạn có 2 loại lớp khác nhau: UIImage và UIView. Cả hai đều có thể được sử dụng để hiển thị bất kỳ hình ảnh nào nhưng cả hai đều thực hiện theo những cách khác nhau. Khá nhiều thứ trong iOS là một lớp con của UIView nhưng chỉ UIImage mới có thể hiển thị hình ảnh (2 thứ khác nhau). Chức năng này thực hiện là lấy UIVIew và chuyển nó thành UIImage. Một ví dụ dễ dàng hơn. Nếu bạn muốn chuyển đổi 4.0 (một Double) thành 4 (một Int), bạn chuyển nó Int (4.0) kết quả là 4. Nhưng với điều này, bạn chuyển đổi hình ảnh bên trong UIVIew thành UIImage. Hiểu biết?
Lance Samaria

những gì tôi đang cố gắng làm là yêu cầu người dùng đến Bộ điều khiển Chế độ xem Bộ sưu tập của tôi và nhấn một nút sẽ hiển thị chế độ xem hiện tại, đây sẽ là Chế độ xem Bộ sưu tập 10x10 và tạo hình ảnh của toàn bộ lưới 10x10 (xin lưu ý rằng toàn bộ lưới không hiển thị đầy đủ trong chế độ xem). Mã của bạn ở trên có giải quyết được trường hợp sử dụng đó không?
Famic Tech

Nút này nằm trong Bộ điều khiển Điều hướng. Người dùng sẽ nhấp vào nó và nó 'sẽ' lấy Chế độ xem Bộ sưu tập được hiển thị dưới bộ điều khiển điều hướng và tạo Hình ảnh của Chế độ xem Bộ sưu tập (một PDF cũng sẽ hoạt động) với tất cả thông tin trong các Ô trong Chế độ xem Bộ sưu tập.
Famic Tech

5
var snapshot = overView.snapshotViewAfterScreenUpdates(false)

hoặc trong mục tiêu-c

UIView* snapshot = [overView snapshotViewAfterScreenUpdates:NO];

ImageView có giống với hình ảnh không? Nếu vậy, làm cách nào để lưu nó vào ứng dụng của tôi?
Sameer Hussain

4

Bạn có thể sử dụng nó một cách dễ dàng bằng cách sử dụng tiện ích mở rộng như thế này

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

Nếu bạn muốn sử dụng các biến / phương thức mở rộng đó, hãy triển khai

  1. Tiện ích mở rộng hình ảnh

    extension UIImage {
        convenience init(view: UIView) {
            if let cgImage = view.snapshot?.cgImage {
                self.init(cgImage: cgImage)
            } else {
                self.init()
            }
        }
    }
  2. Tiện ích mở rộng 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. Tiện ích mở rộng ứng dụng UIA

    extension UIApplication {
    
        var snapshot: UIImage? {
            return keyWindow?.rootViewController?.view.snapshot
        }
    }

Tôi đã xem với các lượt xem phụ mà zPositions đã thao tác và các câu trả lời khác không cung cấp cho tôi vị trí lớp chính xác, cảm ơn bạn.
Ashkan Ghodrat

3

hoặc iOS 10+, bạn có thể sử dụng UIGraphicsImageRenderer mới + drawHierarchy được đề xuất, trong một số trường hợp có thể nhanh hơn nhiều so với 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)
        }
    }
}

3

Cảm ơn @Bao Tuan Diep! Tôi muốn thêm một chất bổ sung.

Khi bạn sử dụng mã:

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

Bạn phải lưu ý rằng:

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

Sau đó, bạn phải sử dụng :

[yourView setNeedsLayout];
[yourView layoutIfNeeded];

để cập nhật yourViewtrước yourView.layer.render(in:UIGraphicsGetCurrentContext()!).

Nếu không, bạn có thể nhận được một đối tượng hình ảnh không chứa phần tử


Cảm ơn vì điều đó. Đã giúp đỡ rất nhiều !!
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)!)

    } 
}

sử dụng:

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


1

Triển khai trong Swift 3 :

Thêm mã bên dưới, ngoài phạm vi lớp học.

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

Sử dụng :

let image = UIImage( Your_View_Outlet )

nhận được lỗi "Vẽ một cái nhìn (0x1040a6970, UIView) mà chưa được trả lại ít nhất một lần đòi hỏi"
Kishu mewara

0

Tôi đã triển khai phương pháp của @Naveed J. như thế này và nó hoạt động như một sự quyến rũ.

Đây là phạm vi của anh ấy:

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

Đây là cách tôi thực hiện nó.

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

0

Trình khởi tạo với UIGraphicsImageRenderer mới có sẵn kể từ 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)!)
  }
}

0

làm việc tốt với tôi!

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

    }

return snapshotImageFromMyView!Gởi 1: Fatal error: Thật bất ngờ tìm thấy con số không trong khi unwrapping một giá trị bắt buộc
Takasur

0

Đối với chế độ xem chứa chế độ xem phụ bị mờ (ví dụ: phiên bản UIVisualEffectView ), chỉ drawViewHierarchyInRect: afterScreenUpdates hoạt động.

Câu trả lời của @ViJay Avhad là chính xác cho trường hợp này.


0

Việc sử dụng UIGraphicsImageRenderer không hoạt động khi chế độ xem có chứa các lượt xem phụ Bộ công cụ cảnh, các chế độ xem Bộ kim loại hoặc Sprite. Trong những trường hợp này, hãy sử dụng

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

-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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.