简体   繁体   English

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

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

I am making an app using Swift 4.0. 我正在使用Swift 4.0开发应用程序。 It is a sort of social media app. 这是一种社交媒体应用程序。 My app has a collectionView (the users feed) with multiple collectionViewCells. 我的应用程序有一个具有多个collectionViewCells的collectionView(用户供稿)。 The problem with this however is that for every cell I have, I am blurring a portion or sometimes all of the image. 但是,这样做的问题是,对于我拥有的每个单元,我都会模糊部分或全部图像。 This causes heavy lag on the device after a couple scrolls to the point where you can barely use it. 夫妇滚动到几乎无法使用设备的位置后,这会在设备上造成严重的延迟。

In order to counter this I thought it would make much more sense instead of blurring the cells image I would just blur it when the user uploads it into the sql database and when it shows up in other users feed/timeline they're iPhone won't have to blur the image because the image they pulled from the database is already pulled. 为了解决这个问题,我认为这将比模糊单元格图像更有意义,而只是在用户将其上传到sql数据库中并且当它出现在其他用户的供稿/时间轴中时,它们就会被iPhone所迷惑。不必模糊图像,因为他们从数据库中提取的图像已经被提取。

I have had some luck turning UIImageViews into UIImages but whenever I render it to an image the blurring effect gets distorted and essentially turns into a white overlay with a some transparency. 我很幸运地将UIImageViews转换为UIImages,但是每当我将其渲染为图像时,模糊效果就会失真,并且实质上变成具有一定透明度的白色覆盖层。

Code for turning UIImageViews into 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!)
    }
}

After that I simply call it with 之后,我简单地用

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)

这就是我得到的

这就是我要的

It may be hard to see but there is no blur in the first image it is just a transparent white overlay 可能很难看到,但第一张图像中没有模糊,只是透明的白色覆盖层

You need to take a snapshot of the container view after the visual effect view is applied. 应用视觉效果视图后,需要对容器视图进行快照。 I will demonstrate a flow which will work. 我将演示一个有效的流程。

Your Controller: 您的控制器:

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

We implement a protocol VisualEffectCustomDelegate to the controller class. 我们为控制器类实现了协议VisualEffectCustomDelegate。

protocol VisualEffectCustomDelegate {

func viewAppeared()
}

Create your own custom class as a child of VisualEffectView class: 创建自己的自定义类作为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()
}
}

The above implementation will work. 以上实现将起作用。 What happens here is as follows: Your controller class confirms to a protocol VisualEffectCustomDelegate, which has a function named viewAppeared. 发生的情况如下:控制器类确认协议VisualEffectCustomDelegate,该协议具有一个名为viewAppeared的函数。 We are going to use this method when we know for sure that the visual effect view is visible in the window. 当我们确定在窗口中可见视觉效果视图时,将使用此方法。 We use the didMoveToWindow method of the UIView class to fire the protocol method. 我们使用UIView类的didMoveToWindow方法来触发协议方法。 When you initiate the CustomVisualEffect view in your controller, pass the controller to the view object. 在控制器中启动CustomVisualEffect视图时,请将控制器传递给视图对象。 I hope this is clear. 我希望这很清楚。

Since you are dealing with a UITableView/UICollectionView, make the changes to the code as you see fit. 由于您正在处理UITableView / UICollectionView,因此请根据需要对代码进行更改。

How Do I Take a Screen Shot of a UIView? 如何拍摄UIView的屏幕截图?

// try like this //这样尝试

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.

相关问题 如何在Swift中将UIImageView置于“模糊效果”之上? - How do I make my UIImageView be on top of the Blur Effect in Swift? 如何在Monotouch中对UIImageView进行运动模糊效果? - How to do a motion blur effect on an UIImageView in Monotouch? 将uiimageview图像转换为uiimage(swift4) - take uiimageview image and convert to uiimage (swift4) 如何在不丢失阴影饱和度的情况下将带阴影的 UIBezierpath 转换为 UIImage - how to convert UIBezierpath with shadow to UIImage without losing the shadow saturation 使UIImage成为一个不损失质量的圆形? (迅速) - Make UIImage a Circle without Losing quality? (swift) 如何在不使用UIImageView的情况下缩小UIImage? - How I can pinch zoom UIImage without using UIImageView? 如何模糊UIImage,但保留清晰的对象边界? - How do I blur a UIImage, but preserve sharp object boundaries? 如何将UIImageView上的触摸限制为其UIImage的不透明部分? - How do I restrict touches on a UIImageView to the opaque parts of its UIImage? 如何使用 Swift 模糊 UIImageView 中的现有图像? - How to blur an existing image in a UIImageView with Swift? 在Swift中将叠加效果从psd转换为UIImage - Convert overlay effect from psd to UIImage in Swift
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM