可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
The setup is simple.
- A ViewController with UIImageView that has an image assigned.
- A UIButton that when clicked blurs the image in the 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?
回答1:
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.
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.
回答2:
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()
回答3:
Here is how I got my expected result in SWIFT 3.1:
Hope it will help.
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
}
回答4:
I made the blur in a NSObject class, so I can use this method in whole project easily.
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.
import UIKit
class ViewController: UIViewController
{
var blurEffectView : UIVisualEffectView!
override func viewDidLoad() {
super.viewDidLoad()
blurEffectView = Helper.addBlurView((imgView)!)
self.imgView.addSubview(blurEffectView)
}
回答5:
Solutions using UIVisualEffectView
or CIFilter
have terrible performance or bad results (producing a blurred bright border around the image as can be seen in Joes answer) or both.
One of the best performing solutions with decent results is StackBlur
which uses a clever algorithm that efficiently approximates a blur:
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.
Check out StackBlur on Github.
There are many versions out there, also Swift ports, but those are considerable slower than the Obj-C versions.
回答6:
You can add blur effect by UIBlurEffect
and 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)
}
回答7:
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:
https://github.com/k-sathireddy/ImageBlurEffect