iOS 8 之后,苹果推出了 UIVisualEffectView 高斯模糊效果,但是有时,我们仅需要轻微的模糊效果,而且模糊程度是可控的。
这时可以使用 vImage 来进行模糊效果处理。
首先导入框架
import Accelerate
// MARK:- 图片模糊效果处理
/// 图片模糊效果处理
/// - parameter image: 需要处理的图片
/// - parameter level: 模糊程度(0~1)
func blurry(_ image: UIImage, level: CGFloat) -> UIImage {
// 处理模糊程度, 防止超出
var levelValue: CGFloat = level
if level < 0 {
levelValue = 0.1
} else if level > 1.0 {
levelValue = 1.0
}
// boxSize 必须大于 0
var boxSize = Int(levelValue * 100)
boxSize -= (boxSize % 2) + 1
let _cgImage = image.cgImage
// 图像缓存: 输入缓存、输出缓存
var inBuffer = vImage_Buffer()
var outBuffer = vImage_Buffer()
var error = vImage_Error()
let inProvider = _cgImage?.dataProvider
let inBitmapData = inProvider?.data
inBuffer.width = vImagePixelCount((_cgImage?.width)!)
inBuffer.height = vImagePixelCount((_cgImage?.height)!)
inBuffer.rowBytes = (_cgImage?.bytesPerRow)!
inBuffer.data = UnsafeMutableRawPointer(mutating: CFDataGetBytePtr(inBitmapData!))
// 像素缓存
let pixelBuffer = malloc((_cgImage?.bytesPerRow)! * (_cgImage?.height)!)
outBuffer.data = pixelBuffer
outBuffer.width = vImagePixelCount((_cgImage?.width)!)
outBuffer.height = vImagePixelCount((_cgImage?.height)!)
outBuffer.rowBytes = (_cgImage?.bytesPerRow)!
// 中间缓存区, 抗锯齿
let pixelBuffer2 = malloc((_cgImage?.bytesPerRow)! * (_cgImage?.height)!)
var outBuffer2 = vImage_Buffer()
outBuffer2.data = pixelBuffer2
outBuffer2.width = vImagePixelCount((_cgImage?.width)!)
outBuffer2.height = vImagePixelCount((_cgImage?.height)!)
outBuffer2.rowBytes = (_cgImage?.bytesPerRow)!
error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer2, nil, 0, 0, UInt32(boxSize), UInt32(boxSize), nil, vImage_Flags(kvImageEdgeExtend))
error = vImageBoxConvolve_ARGB8888(&outBuffer2, &outBuffer, nil, 0, 0, UInt32(boxSize), UInt32(boxSize), nil, vImage_Flags(kvImageEdgeExtend))
if error != kvImageNoError {
debugPrint(error)
}
let colorSpace = CGColorSpaceCreateDeviceRGB()
let ctx = CGContext(data: outBuffer.data, width: Int(outBuffer.width), height: Int(outBuffer.height), bitsPerComponent: 8, bytesPerRow: outBuffer.rowBytes, space: colorSpace, bitmapInfo: (_cgImage?.bitmapInfo.rawValue)!)
let finalCGImage = ctx!.makeImage()
let finalImage = UIImage(cgImage: finalCGImage!)
free(pixelBuffer!)
free(pixelBuffer2!)
return finalImage
}