簡體   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