ios 如何使用 Swift 在 UIImageView 中模糊现有图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41156542/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to blur an existing image in a UIImageView with Swift?
提问by Mark Moeykens
The setup is simple.
设置很简单。
- A ViewController with UIImageView that has an image assigned.
- A UIButton that when clicked blurs the image in the UIImageView.
- 带有 UIImageView 的 ViewController 分配了图像。
- 一个 UIButton,在单击时会模糊 UIImageView 中的图像。
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!)
}
}
When the button is clicked the screen just turns white. Can't figure out what I'm doing wrong. Anyone know what I'm doing wrong?
单击按钮时,屏幕会变成白色。无法弄清楚我做错了什么。有谁知道我做错了什么?
回答by Joe
You could simply use UIVisualEffect
to achieve blur effect. As you trying to achieve a blur effect using CoreImage.Try below code after import CoreImage
to your class.
您可以简单地使用UIVisualEffect
来实现模糊效果。当您尝试使用 CoreImage.Try 下面的代码实现模糊效果时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
}
Output:
输出:
Note:I recommend you to test the code in real device as Simulator performance is too slow on coreImage.
注意:我建议您在真实设备中测试代码,因为模拟器在 coreImage 上的性能太慢。
回答by kaushal.exe
for those who ?? protocols
对于那些人??协议
protocol Bluring {
func addBlur(_ alpha: CGFloat)
}
extension Bluring 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: Bluring {}
// use
someImageview.addBlur()
回答by Md Milan Mia
Here is how I got my expected result in SWIFT 3.1: Hope it will help.
以下是我在 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
}
回答by Manuel
A good performing solution with decent results is StackBlur
which uses a clever algorithm that efficiently approximates a blur:
一个性能良好且结果不错的解决方案是StackBlur
使用一种巧妙的算法来有效地近似模糊:
This is a compromise between Gaussian Blur and Box blur It creates much better looking blurs than Box Blur, but is 7x faster than my Gaussian Blur implementation. I called it Stack Blur because this describes best how this filter works internally: it creates a kind of moving stack (or maybe a "Tower of Hanoi" kind of structure) of colors whilst scanning through the image. This "tower" controls the weights of the single pixels within the convolution kernel and gives the pixel in the center the highest weight. The secret of the speed is that the algorithm just has to add one new pixel to the right side of the stack and at the same time remove the leftmost pixel. The remaining colors on the topmost layer of the stack are either added on or reduced by one, depending on if they are on the right or on the left side of the stack.
这是高斯模糊和框模糊之间的折衷。它创建的模糊效果比框模糊要好得多,但比我的高斯模糊实现快 7 倍。我称它为堆栈模糊,因为它最好地描述了这个过滤器的内部工作方式:它在扫描图像的同时创建了一种移动的堆栈(或者可能是“河内之塔”类型的结构)颜色。这个“塔”控制着卷积核内单个像素的权重,并赋予中心像素最高的权重。速度的秘诀在于算法只需在堆栈的右侧添加一个新像素,同时删除最左侧的像素。堆栈最顶层的剩余颜色要么加一,要么减一,
Check out StackBlur on Github.
There are many versions out there, also Swift ports, but those are considerable slower than the Obj-C versions.
有很多版本,还有 Swift 端口,但它们比 Obj-C 版本慢得多。
Addition 2019:
2019 年新增:
If the images to blur are remotely loaded, I can highly recommend the Nukeframework that remotely loads images and can apply a blur filter out of the box. It's application is comparable to the Glide library on Android. While blurring one image may be easy, blurring many images - like in a collection view - while considering device resource constraints is less trivial. Nuke is highly optimized for remote image loading, caching and processing. It is also extendable in several aspects. From comparing available remote image loading frameworks, I think that Nuke is the most stable and most advanced for that purpose as of Nov 2019.
如果要模糊的图像是远程加载的,我强烈推荐Nuke框架,它可以远程加载图像并且可以应用开箱即用的模糊过滤器。它的应用程序可与 Android 上的 Glide 库相媲美。虽然模糊一张图像可能很容易,但在考虑设备资源限制的情况下模糊许多图像(例如在集合视图中)则不那么简单。Nuke 针对远程图像加载、缓存和处理进行了高度优化。它也可以在几个方面进行扩展。通过比较可用的远程图像加载框架,我认为截至 2019 年 11 月,Nuke 是最稳定和最先进的。
回答by KSR
Use this:
用这个:
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
}
}
Output:
输出:
Gitbub link:
gitbub 链接:
回答by Pedro Ortiz
Check if something is coming nil. I had a similar issue, but in my case I wasn't creating a new instance of CIImage, because of that image.ciimage was coming nil.
检查是否有东西为零。我有一个类似的问题,但就我而言,我没有创建 CIImage 的新实例,因为 image.ciimage 即将为零。
回答by Amanpreet
I made the blur in a NSObject class, so I can use this method in whole project easily.
我在 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
}
}
In ViewController I made object of UIVisualEffectView. Then call the helper class method of to add blur.
在 ViewController 中,我创建了UIVisualEffectView 的对象。然后调用辅助类方法添加模糊。
import UIKit
class ViewController: UIViewController
{
var blurEffectView : UIVisualEffectView!
override func viewDidLoad() {
super.viewDidLoad()
blurEffectView = Helper.addBlurView((imgView)!)
self.imgView.addSubview(blurEffectView)
}
回答by Bhavin Ramani
You can add blur effect by UIBlurEffect
and UIVisualEffectView
:
您可以通过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)
}
回答by LeoNard
Hey to all the LAZY guys just like me.
嘿所有像我一样的懒人。
Just add SwifterSwift with cocoapods.
只需将 SwifterSwift 添加到 cocoapods 即可。
Import SwifterSwift.
导入 SwifterSwift。
import SwifterSwift
Blur your image view just like below.
像下面一样模糊您的图像视图。
someImageView.blur()