你说:
- 我想拍摄带有模糊的屏幕截图,因为模糊滤镜永远不会保存在屏幕截图中。
我想知道被快照的视图是否可能不是UIVisualEffectView
作为子视图的视图。因为当我在答案末尾使用代码时,fractionCompleted
会捕获模糊效果(以及更改 的影响)。
- 图像质量非常低。
如果您使用UIGraphicsBeginImageContextWithOptions
零比例,它应该以设备的分辨率捕获图像:
UIGraphicsBeginImageContextWithOptions(size, isOpaque, 0)
- 我无法裁剪图像。
我个人捕捉整个视图,然后根据需要进行裁剪。请参阅UIView
下面的扩展。
在斯威夫特 3 中:
class ViewController: UIViewController {
var animator: UIViewPropertyAnimator?
@IBOutlet weak var imageView: UIImageView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let blur = UIBlurEffect(style: .light)
let effectView = UIVisualEffectView(effect: blur)
view.addSubview(effectView)
effectView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
effectView.leadingAnchor.constraint(equalTo: imageView.leadingAnchor),
effectView.trailingAnchor.constraint(equalTo: imageView.trailingAnchor),
effectView.topAnchor.constraint(equalTo: imageView.topAnchor),
effectView.bottomAnchor.constraint(equalTo: imageView.bottomAnchor)
])
animator = UIViewPropertyAnimator(duration: 0, curve: .linear) { effectView.effect = nil }
}
@IBAction func didChangeValueForSlider(_ sender: UISlider) {
animator?.fractionComplete = CGFloat(sender.value)
}
@IBAction func didTapSnapshotButton(_ sender: AnyObject) {
if let snapshot = view.snapshot(of: imageView.frame) {
UIImageWriteToSavedPhotosAlbum(snapshot, nil, nil, nil)
}
}
}
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)
}
}
}
或者在 Swift 2 中:
class ViewController: UIViewController {
var animator: UIViewPropertyAnimator?
@IBOutlet weak var imageView: UIImageView!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let blur = UIBlurEffect(style: .Light)
let effectView = UIVisualEffectView(effect: blur)
view.addSubview(effectView)
effectView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activateConstraints([
effectView.leadingAnchor.constraintEqualToAnchor(imageView.leadingAnchor),
effectView.trailingAnchor.constraintEqualToAnchor(imageView.trailingAnchor),
effectView.topAnchor.constraintEqualToAnchor(imageView.topAnchor),
effectView.bottomAnchor.constraintEqualToAnchor(imageView.bottomAnchor)
])
animator = UIViewPropertyAnimator(duration: 0, curve: .Linear) { effectView.effect = nil }
}
@IBAction func didChangeValueForSlider(sender: UISlider) {
animator?.fractionComplete = CGFloat(sender.value)
}
@IBAction func didTapSnapshotButton(sender: AnyObject) {
if let snapshot = view.snapshot(of: imageView.frame) {
UIImageWriteToSavedPhotosAlbum(snapshot, nil, nil, nil)
}
}
}
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)
}
}
因此,当我在四个不同的滑块位置捕获四个图像时,会产生: