Core Image
Core Image是苹果用来简化图片处理的框架,在iOS6.0才开始支持模糊。
func blurImage(_ image: UIImage, blurLevel:CGFloat) -> UIImage {
// 创建属性
let ciImage = CIImage(image: image);
// 滤镜效果 高斯模糊
let filter = CIFilter(name: "CIGaussianBlur");
filter?.setValue(ciImage, forKey: kCIInputImageKey);
// 指定模糊值 默认为10, 范围为0-100
filter?.setValue(blurLevel, forKey: kCIInputRadiusKey);
// 生成图片
let context = CIContext(options: nil);
// 创建输出
let result = filter?.value(forKey: kCIOutputImageKey) as! CIImage;
// 下面这一行的代码耗费时间内存最多,可以开辟线程处理然后回调主线程给imageView赋值
// result.extent 指原来的大小size
let outImage = context.createCGImage(result, from: result.extent);
let blurImage = UIImage(cgImage: outImage!);
return blurImage;
}
vImage
vImage也是苹果推出的库,在Accelerate.framework中。
func blurImage(_ image: UIImage, blurLevel:CGFloat) -> UIImage? {
//需要引入import Accelerate
//模糊度
var blur = blurLevel;
if (blur < 0.025) {
blur = 0.025;
} else if (blur > 1.0) {
blur = 1.0;
}
//boxSize必须大于0
var boxSize = Int(blur * 100);
boxSize -= (boxSize % 2) + 1;
//图像处理
let cgImage = image.cgImage!;
//图像缓存,输入缓存,输出缓存
var inBuffer = vImage_Buffer();
var outBuffer = vImage_Buffer();
//数据源提供者,Defines an opaque type that supplies Quartz with data.
var inProvider = cgImage.dataProvider;
let inBitmapData = inProvider?.data;
//宽,高,字节/行,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;
//Convolves a region of interest within an ARGB8888 source image by an implicit M x N kernel that has the effect of a box filter.
var error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer2, nil, vImagePixelCount(0), vImagePixelCount(0), UInt32(boxSize), UInt32(boxSize), nil, vImage_Flags(kvImageEdgeExtend));
if (error != kvImageNoError) {
return nil;
}
error = vImageBoxConvolve_ARGB8888(&outBuffer2, &inBuffer, nil, vImagePixelCount(0), vImagePixelCount(0), UInt32(boxSize), UInt32(boxSize), nil, vImage_Flags(kvImageEdgeExtend));
if (error != kvImageNoError) {
return nil;
}
error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, nil, vImagePixelCount(0), vImagePixelCount(0), UInt32(boxSize), UInt32(boxSize), nil, vImage_Flags(kvImageEdgeExtend));
if (error != kvImageNoError) {
return nil;
}
//颜色空间DeviceRGB
let colorSpace = CGColorSpaceCreateDeviceRGB();
//用图片创建上下文,CGImageGetBitsPerComponent(img),7,8
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 imageRef = ctx?.makeImage();
let returnImage = UIImage(cgImage: imageRef!);
//clean up
free(pixelBuffer);
free(pixelBuffer2);
return returnImage;
}
UIVisualEffectView
UIVisualEffectView是iOS8.0以后苹果才提供的方法,且不能修改模糊半径,有一定的局限性,但是使用简单。
let blurEffect = UIBlurEffect(style: .light);
let effectView = UIVisualEffectView(effect: blurEffect);
effectView.frame = imageView.frame;
self.view.addSubview(effectView);
第三方工具/库推荐
FXBlurView
FXBlurView是一个UIView的子类,效果和iOS7的背景实时模糊效果一样。FXBlurView 有两种模式,一种是 static 静态模糊:也就是只模糊一次,后面即使背景图片变化了,模糊效果也不会变化;另外就是 dynamic 动态模糊:这会实时的对背景图片进行模糊,是会不断变化的。
GPUImage
GPUImage 是一个基于GPU图像和视频处理开源的iOS framework,适用面很广。
UIImageEffects
UIImageEffects苹果官方提供的利用vImage实现的模糊处理。