如何获取部分UIView的屏幕截图? [英] How to take screenshot of portion of UIView?
问题描述
我希望用户在Swift中以编程方式按下按钮后继续运行我的应用并拍摄该应用的屏幕截图.我知道UIGraphicsGetImageFromCurrentImageContext()
需要一个屏幕截图,但是我不想要整个屏幕的图片.我希望弹出一个矩形(有点像裁剪工具),并且用户可以拖动矩形并调整其大小以仅截取屏幕的特定部分的屏幕截图.我希望矩形越过WKWebView
并裁剪Web视图的图片.
I want the user to go on my app and take a screenshot of the app after pressing a button programmatically in Swift. I know that UIGraphicsGetImageFromCurrentImageContext()
takes a screenshot but I don't want a picture of the entire screen. I want a rectangle to pop up (sort of like a crop tool) and the user can drag and resize the rectangle to take a screenshot of only a certain part of the screen. I want the rectangle to go over a WKWebView
and crop a pic of the web view.
推荐答案
标准快照技术是 UIGraphicsImageRenderer
:
The standard snapshot technique is drawHierarchy(in:afterScreenUpdates:)
, drawing that to an image context. In iOS 10 and later, you can use UIGraphicsImageRenderer
:
extension UIView {
/// Create image snapshot of view.
///
/// - Parameters:
/// - rect: The coordinates (in the view's own coordinate space) to be captured. If omitted, the entire `bounds` will be captured.
/// - afterScreenUpdates: A Boolean value that indicates whether the snapshot should be rendered after recent changes have been incorporated. Specify the value false if you want to render a snapshot in the view hierarchy’s current state, which might not include recent changes. Defaults to `true`.
///
/// - Returns: The `UIImage` snapshot.
func snapshot(of rect: CGRect? = nil, afterScreenUpdates: Bool = true) -> UIImage {
return UIGraphicsImageRenderer(bounds: rect ?? bounds).image { _ in
drawHierarchy(in: bounds, afterScreenUpdates: afterScreenUpdates)
}
}
}
您将这样使用:
let image = webView.snapshot(of: rect)
在iOS 10之前,您需要获取图像的一部分,可以使用CGImage
方法 cropping(to:)
.例如:
Prior to iOS 10, you would to get portion of an image, you can use CGImage
method cropping(to:)
. E.g.:
extension UIView {
/// Create snapshot
///
/// - Parameters:
/// - rect: The coordinates (in the view's own coordinate space) to be captured. If omitted, the entire `bounds` will be captured.
/// - afterScreenUpdates: A Boolean value that indicates whether the snapshot should be rendered after recent changes have been incorporated. Specify the value false if you want to render a snapshot in the view hierarchy’s current state, which might not include recent changes. Defaults to `true`.
///
/// - Returns: Returns `UIImage` of the specified portion of the view.
func snapshot(of rect: CGRect? = nil, afterScreenUpdates: Bool = true) -> UIImage? {
// snapshot entire view
UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0)
drawHierarchy(in: bounds, afterScreenUpdates: afterScreenUpdates)
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
guard let cgImage = image.cgImage?.cropping(to: rect * image.scale) else { return nil }
return UIImage(cgImage: cgImage, scale: image.scale, orientation: .up)
}
}
哪个使用这个方便的运算符:
Which uses this little convenient operator:
extension CGRect {
static func * (lhs: CGRect, rhs: CGFloat) -> CGRect {
return CGRect(x: lhs.minX * rhs, y: lhs.minY * rhs, width: lhs.width * rhs, height: lhs.height * rhs)
}
}
要使用它,您可以执行以下操作:
And to use it, you can do:
if let image = webView.snapshot(of: rect) {
// do something with `image` here
}
有关Swift 2再现,请参见此答案的先前版本.
这篇关于如何获取部分UIView的屏幕截图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!