如何截取部分UIView的截图?

我希望用户继续我的应用程序,并在Swift中按编程button后,应用程序的屏幕截图。 我知道UIGraphicsGetImageFromCurrentImageContext()需要截图,但我不想要整个屏幕的图片。 我想要一个矩形popup(有点像一个裁剪工具),用户可以拖动和调整矩形只截取屏幕的某一部分的屏幕截图。 我想要矩形通过WKWebView并裁剪Web视图的图片。

标准快照技术是drawViewHierarchyInRect 。 要获取图像的一部分,可以使用CGImageCreateWithImageInRect

因此,在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) } } 

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

要使用它,你可以这样做:

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

这是以前问的问题, 如何捕捉UIView到UIImage没有质量损失的视网膜显示,但要迅速扩大(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) } } 

所以你可以从UIView.image(theView)的视图中获取图像,或者通过让视图本身let viewImage = self.view.image()

请记住,这是粗糙的,可能需要进一步寻找线程安全等….