繁体   English   中英

Swift如何在不丢失模糊效果的情况下将UIImageView转换为UIImage

[英]Swift How do I convert a UIImageView into a UIImage Without Losing blur effect

我正在使用Swift 4.0开发应用程序。 这是一种社交媒体应用程序。 我的应用程序有一个具有多个collectionViewCells的collectionView(用户供稿)。 但是,这样做的问题是,对于我拥有的每个单元,我都会模糊部分或全部图像。 夫妇滚动到几乎无法使用设备的位置后,这会在设备上造成严重的延迟。

为了解决这个问题,我认为这将比模糊单元格图像更有意义,而只是在用户将其上传到sql数据库中并且当它出现在其他用户的供稿/时间轴中时,它们就会被iPhone所迷惑。不必模糊图像,因为他们从数据库中提取的图像已经被提取。

我很幸运地将UIImageViews转换为UIImages,但是每当我将其渲染为图像时,模糊效果就会失真,并且实质上变成具有一定透明度的白色覆盖层。

用于将UIImageViews转换为UIImages的代码:

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

之后,我简单地用

let background = UIImageView(frame: CGRect(x: 0, y: 0, width: cell.frame.width, height: 200))
background.image = profileImage
let label = UIBlurEffect(style: UIBlurEffectStyle.prominent)
let blurEffectView = UIVisualEffectView(effect: label)
blurEffectView.frame = CGRect(x: 0, y: 0, width: background.frame.width, height: background.frame.height)
background.addSubview(blurEffectView)
let secondImage = UIImage(view: background)

这就是我得到的

这就是我要的

可能很难看到,但第一张图像中没有模糊,只是透明的白色覆盖层

应用视觉效果视图后,需要对容器视图进行快照。 我将演示一个有效的流程。

您的控制器:

class PreviewController: UIViewController,VisualEffectCustomDelegate{
@IBOutlet weak var screenshotView: UIView!
@IBOutlet weak var previewImageView: UIImageView!


override func viewDidLoad() {
    super.viewDidLoad()


    addBlur()
}

func addBlur(){
    let label = UIBlurEffect(style: UIBlurEffectStyle.prominent)
    let blurEffectView = CustomVisualEffect(effect: label)
    blurEffectView.frame = CGRect(x: 0, y: 0, width: screenshotView.frame.width, height: screenshotView.frame.height)
    blurEffectView.delegate = self
    screenshotView.addSubview(blurEffectView)

}

func viewAppeared() {
    print("Appeared")
    previewImageView.image = screenshotView.screenShot
}


}


extension UIView {

var screenShot: UIImage?  {
    UIGraphicsBeginImageContextWithOptions(bounds.size, false, 1.0);
    if let _ = UIGraphicsGetCurrentContext() {
        drawHierarchy(in: bounds, afterScreenUpdates: true)
        let screenshot = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return screenshot
    }
    return nil
}
}

我们为控制器类实现了协议VisualEffectCustomDelegate。

protocol VisualEffectCustomDelegate {

func viewAppeared()
}

创建自己的自定义类作为VisualEffectView类的子类:

class CustomVisualEffect: UIVisualEffectView {

var delegate: VisualEffectCustomDelegate!

override init(effect: UIVisualEffect?) {
    super.init(effect: effect)
}

convenience init(){
    self.init()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override func didMoveToWindow() {
    print("Visible Now")
    delegate.viewAppeared()
}
}

以上实现将起作用。 发生的情况如下:控制器类确认协议VisualEffectCustomDelegate,该协议具有一个名为viewAppeared的函数。 当我们确定在窗口中可见视觉效果视图时,将使用此方法。 我们使用UIView类的didMoveToWindow方法来触发协议方法。 在控制器中启动CustomVisualEffect视图时,请将控制器传递给视图对象。 我希望这很清楚。

由于您正在处理UITableView / UICollectionView,因此请根据需要对代码进行更改。

如何拍摄UIView的屏幕截图?

//这样尝试

public extension UIImageView {
public func snapshotImage() -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0)
    drawHierarchy(in: bounds, afterScreenUpdates: false)
    let snapshotImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return snapshotImage
}

}

// get image from your imageview 
 let image = background.snapshotImage()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM