Swift如何将UIImageView转换为UIImage而不会失去模糊效果

时间:2018-02-17 05:28:40

标签: ios swift uiimageview uiimage

我正在使用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)

This Is What I Get

This Is What I Want

可能很难看到,但第一张图片中没有模糊,只是透明的白色叠加

2 个答案:

答案 0 :(得分:0)

应用视觉效果视图后,您需要拍摄容器视图的快照。我将演示一个可行的流程。

你的控制器:

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,请根据需要对代码进行更改。

How Do I Take a Screen Shot of a UIView?

答案 1 :(得分:0)

//试试这个

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()