2016-09-02 19 views
6

Tôi muốn người dùng truy cập ứng dụng của tôi và chụp ảnh màn hình ứng dụng sau khi nhấn một nút lập trình trong Swift. Tôi biết rằng UIGraphicsGetImageFromCurrentImageContext() có ảnh chụp màn hình nhưng tôi không muốn ảnh của toàn bộ màn hình. Tôi muốn một hình chữ nhật để bật lên (loại giống như một công cụ cắt) và người dùng có thể kéo và thay đổi kích thước hình chữ nhật để có một ảnh chụp màn hình của chỉ một phần nhất định của màn hình. Tôi muốn hình chữ nhật đi qua một hình ảnh WKWebView và cắt một pic của chế độ xem web.Cách chụp màn hình phần của UIView?

Trả lời

16

Kỹ thuật chụp nhanh tiêu chuẩn là drawViewHierarchyInRect. Và để lấy một phần của hình ảnh, bạn có thể sử dụng CGImageCreateWithImageInRect.

Như vậy, trong Swift 2:

extension UIView { 

    /// Create snapshot 
    /// 
    /// - parameter rect: The `CGRect` of the portion of the view to return. If `nil` (or omitted), 
    ///     return snapshot of the whole view. 
    /// 
    /// - returns: Returns `UIImage` of the specified portion of the view. 

    func snapshot(of rect: CGRect? = nil) -> UIImage? { 
     // snapshot entire view 

     UIGraphicsBeginImageContextWithOptions(bounds.size, opaque, 0) 
     drawViewHierarchyInRect(bounds, afterScreenUpdates: true) 
     let wholeImage = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     // if no `rect` provided, return image of whole view 

     guard let rect = rect, let image = wholeImage else { return wholeImage } 

     // otherwise, grab specified `rect` of image 

     let scale = image.scale 
     let scaledRect = CGRect(x: rect.origin.x * scale, y: rect.origin.y * scale, width: rect.size.width * scale, height: rect.size.height * scale) 
     guard let cgImage = CGImageCreateWithImageInRect(image.CGImage!, scaledRect) else { return nil } 
     return UIImage(CGImage: cgImage, scale: scale, orientation: .Up) 
    } 

} 

Trong Swift 3:

extension UIView { 

    /// Create snapshot 
    /// 
    /// - parameter rect: The `CGRect` of the portion of the view to return. If `nil` (or omitted), 
    ///     return snapshot of the whole view. 
    /// 
    /// - returns: Returns `UIImage` of the specified portion of the view. 

    func snapshot(of rect: CGRect? = nil) -> UIImage? { 
     // snapshot entire view 

     UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0) 
     drawHierarchy(in: bounds, afterScreenUpdates: true) 
     let wholeImage = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     // if no `rect` provided, return image of whole view 

     guard let image = wholeImage, let rect = rect else { return wholeImage } 

     // otherwise, grab specified `rect` of image 

     let scale = image.scale 
     let scaledRect = CGRect(x: rect.origin.x * scale, y: rect.origin.y * scale, width: rect.size.width * scale, height: rect.size.height * scale) 
     guard let cgImage = image.cgImage?.cropping(to: scaledRect) else { return nil } 
     return UIImage(cgImage: cgImage, scale: scale, orientation: .up) 
    } 

} 

Và để sử dụng nó, bạn có thể làm:

if let image = webView.snapshot(of: rect) { 
    // do something with `image` here 
} 
+1

lớn công việc như mọi khi Rob. Cảm ơn. – damirstuhec

+0

Giải pháp hoàn hảo. Có những cái khác trên SO nhưng chúng chiếm toàn bộ màn hình. Đây là giải pháp cho cả hai. – Septronic

3

Đây là một câu hỏi hỏi trước tại How to capture UIView to UIImage without loss of quality on retina display nhưng để mở rộng trong nhanh chóng (2.3):

extension UIView { 

    class func image(view: UIView) -> UIImage? { 
     UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0) 
     guard let ctx = UIGraphicsGetCurrentContext() else { 
      return nil 
     } 
     view.layer.renderInContext(ctx) 
     let img = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 
     return img 
    } 

    func image() -> UIImage? { 
     return UIView.image(self) 
    } 
} 

Vì vậy, bạn có thể có được một hình ảnh từ một cái nhìn với UIView.image(theView) hoặc bằng cách yêu cầu xem bản thân let viewImage = self.view.image()

Hãy ghi nhớ mặc dù điều này là thô và có thể cần tiếp tục xem xét cho an toàn chủ đề vv.

Các vấn đề liên quan