[英]How to blur an existing image in a UIImageView with Swift?
设置很简单。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var bg: UIImageView!
@IBAction func blur(_ sender: Any) {
let inputImage = CIImage(cgImage: (bg.image?.cgImage)!)
let filter = CIFilter(name: "CIGaussianBlur")
filter?.setValue(inputImage, forKey: "inputImage")
filter?.setValue(10, forKey: "inputRadius")
let blurred = filter?.outputImage
bg.image = UIImage(ciImage: blurred!)
}
}
单击按钮时,屏幕将变为白色。 无法弄清楚我做错了什么。 有人知道我在做什么错吗?
您可以简单地使用UIVisualEffect
来实现模糊效果。 当您尝试使用 CoreImage 实现模糊效果时。在import CoreImage
您的类后尝试下面的代码。
var context = CIContext(options: nil)
func blurEffect() {
let currentFilter = CIFilter(name: "CIGaussianBlur")
let beginImage = CIImage(image: bg.image!)
currentFilter!.setValue(beginImage, forKey: kCIInputImageKey)
currentFilter!.setValue(10, forKey: kCIInputRadiusKey)
let cropFilter = CIFilter(name: "CICrop")
cropFilter!.setValue(currentFilter!.outputImage, forKey: kCIInputImageKey)
cropFilter!.setValue(CIVector(cgRect: beginImage!.extent), forKey: "inputRectangle")
let output = cropFilter!.outputImage
let cgimg = context.createCGImage(output!, from: output!.extent)
let processedImage = UIImage(cgImage: cgimg!)
bg.image = processedImage
}
输出:
注意:我建议您在真实设备中测试代码,因为模拟器在 coreImage 上的性能太慢。
对于那些❤️协议的人
protocol Blurable {
func addBlur(_ alpha: CGFloat)
}
extension Blurable where Self: UIView {
func addBlur(_ alpha: CGFloat = 0.5) {
// create effect
let effect = UIBlurEffect(style: .dark)
let effectView = UIVisualEffectView(effect: effect)
// set boundry and alpha
effectView.frame = self.bounds
effectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
effectView.alpha = alpha
self.addSubview(effectView)
}
}
// Conformance
extension UIView: Blurable {}
// use
someImageview.addBlur()
以下是我在 SWIFT 3.1 中获得预期结果的方式:希望它会有所帮助。
func blurImage(image:UIImage) -> UIImage? {
let context = CIContext(options: nil)
let inputImage = CIImage(image: image)
let originalOrientation = image.imageOrientation
let originalScale = image.scale
let filter = CIFilter(name: "CIGaussianBlur")
filter?.setValue(inputImage, forKey: kCIInputImageKey)
filter?.setValue(10.0, forKey: kCIInputRadiusKey)
let outputImage = filter?.outputImage
var cgImage:CGImage?
if let asd = outputImage
{
cgImage = context.createCGImage(asd, from: (inputImage?.extent)!)
}
if let cgImageA = cgImage
{
return UIImage(cgImage: cgImageA, scale: originalScale, orientation: originalOrientation)
}
return nil
}
CoreImage 实际上有一个方便的实现https://developer.apple.com/documentation/coreimage/ciimage/1645897-applyinggaussianblur
extension UIImage {
func blur(_ radius: Double) -> UIImage? {
if let img = CIImage(image: self) {
return UIImage(ciImage: img.applyingGaussianBlur(sigma: radius))
}
return nil
}
StackBlur
是一个效果不错且性能良好的解决方案,它使用一种巧妙的算法来有效地逼近模糊:
这是 Gaussian Blur 和 Box blur 之间的折衷方案。它创建的模糊效果比 Box Blur 好得多,但比我的 Gaussian Blur 实现快 7 倍。 我将其命名为堆栈模糊,因为它最好地描述了此滤镜在内部的工作方式:它在扫描图像时创建一种移动的颜色堆栈(或者可能是“河内之塔”类型的结构)。 这个“塔”控制卷积核内单个像素的权重,并赋予中心像素最高的权重。 速度的秘诀在于该算法只需在堆栈的右侧添加一个新像素,同时移除最左侧的像素。 堆栈最顶层的剩余颜色要么加一,要么减一,具体取决于它们是在堆栈的右侧还是左侧。
那里有很多版本,还有 Swift 端口,但这些版本比 Obj-C 版本慢很多。
如果要模糊的图像是远程加载的,我强烈推荐Nuke框架,它可以远程加载图像并可以开箱即用地应用模糊过滤器。 它的应用程序可与 Android 上的 Glide 库相媲美。 虽然模糊一张图像可能很容易,但在考虑设备资源限制的同时模糊许多图像(例如在集合视图中)就不那么简单了。 Nuke 针对远程图像加载、缓存和处理进行了高度优化。 它还可以在多个方面进行扩展。 通过比较可用的远程图像加载框架,我认为 Nuke 是截至 2019 年 11 月为止最稳定和最先进的。
用这个:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var bgImageView: UIImageView!
@IBOutlet weak var blurButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func blurButtonTapped(_ sender: Any) {
let inputImage = CIImage(cgImage: (self.bgImageView.image?.cgImage)!)
let filter = CIFilter(name: "CIGaussianBlur")
filter?.setValue(inputImage, forKey: "inputImage")
filter?.setValue(10, forKey: "inputRadius")
let blurred = filter?.outputImage
var newImageSize: CGRect = (blurred?.extent)!
newImageSize.origin.x += (newImageSize.size.width - (self.bgImageView.image?.size.width)!) / 2
newImageSize.origin.y += (newImageSize.size.height - (self.bgImageView.image?.size.height)!) / 2
newImageSize.size = (self.bgImageView.image?.size)!
let resultImage: CIImage = filter?.value(forKey: "outputImage") as! CIImage
let context: CIContext = CIContext.init(options: nil)
let cgimg: CGImage = context.createCGImage(resultImage, from: newImageSize)!
let blurredImage: UIImage = UIImage.init(cgImage: cgimg)
self.bgImageView.image = blurredImage
}
}
我的分机
extension UIImage {
func blurImage(radius: CGFloat = 10) -> UIImage? {
guard let cgImage = cgImage else { return nil }
let inputCIImage = CIImage(cgImage: cgImage)
let context = CIContext(options: nil)
let filter = CIFilter(name: "CIGaussianBlur")
filter?.setValue(inputImage, forKey: kCIInputImageKey)
filter?.setValue(radius, forKey: kCIInputRadiusKey)
let outputImage = filter?.outputImage
if let outputImage = outputImage,
let cgImage = context.createCGImage(outputImage, from: inputImage.extent) {
return UIImage(
cgImage: cgImage,
scale: scale,
orientation: imageOrientation
)
}
return nil
}
}
我在一个 NSObject 类中做了模糊处理,所以我可以很容易地在整个项目中使用这个方法。
class Helper: NSObject
{
class func addBlurView(_ inView : UIView) -> UIVisualEffectView
{
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView.frame = inView.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
blurEffectView.alpha = 0.5
return blurEffectView
}
}
在 ViewController 中,我创建了UIVisualEffectView的对象。 然后调用辅助类方法来添加模糊。
import UIKit
class ViewController: UIViewController
{
var blurEffectView : UIVisualEffectView!
override func viewDidLoad() {
super.viewDidLoad()
blurEffectView = Helper.addBlurView((imgView)!)
self.imgView.addSubview(blurEffectView)
}
检查是否有什么东西是零。 我遇到了类似的问题,但在我的情况下,我没有创建 CIImage 的新实例,因为 image.ciimage 将为零。
您可以通过UIBlurEffect
和UIVisualEffectView
添加模糊效果:
@IBAction func blur(_ sender: Any) {
let darkBlur = UIBlurEffect(style: UIBlurEffectStyle.dark)
let blurView = UIVisualEffectView(effect: darkBlur)
blurView.frame = bg_imagview.bounds
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
bg_imagview.addSubview(blurView)
}
嘿,所有像我一样的懒人。
只需将 SwifterSwift 与 cocoapods 一起添加即可。
导入 SwifterSwift。
import SwifterSwift
像下面一样模糊您的图像视图。
someImageView.blur()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.