图片高斯模糊

使用vImage的高斯模糊

前言

vImage属于Accelerate.Framework,需要导入 Accelerate下的 Accelerate头文件, Accelerate主要是用来做数字信号处理、图像处理相关的向量、矩阵运算的库。图像可以认为是由向量或者矩阵数据构成的,Accelerate里既然提供了高效的数学运算API,自然就能方便我们对图像做各种各样的处理 ,模糊算法使用的是vImageBoxConvolve_ARGB8888这个函数。

OC

+(UIImage *)boxblurImage:(UIImage *)image withBlurNumber:(CGFloat)blur
 { 
     if (blur < 0.f || blur > 1.f) {
        blur = 0.5f; 
     }
     int boxSize = (int)(blur * 40);
     boxSize = boxSize - (boxSize % 2) + 1; 
     CGImageRef img = image.CGImage; 
     vImage_Buffer inBuffer, outBuffer; 
     vImage_Error error; 
     void *pixelBuffer; 
     //从CGImage中获取数据
     CGDataProviderRef inProvider = CGImageGetDataProvider(img);
     CFDataRef inBitmapData = CGDataProviderCopyData(inProvider); 
     //设置从CGImage获取对象的属性 
     inBuffer.width = CGImageGetWidth(img);
     inBuffer.height = CGImageGetHeight(img); 
     inBuffer.rowBytes = CGImageGetBytesPerRow(img); 
     inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData); 
     pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));         
     if(pixelBuffer == NULL)
         NSLog(@"No pixelbuffer"); 
     outBuffer.data = pixelBuffer; 
     outBuffer.width = CGImageGetWidth(img); 
     outBuffer.height = CGImageGetHeight(img); 
     outBuffer.rowBytes = CGImageGetBytesPerRow(img);
     error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
     if (error) { 
           NSLog(@"error from convolution %ld", error); 
     } 
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
     CGContextRef ctx = CGBitmapContextCreate( outBuffer.data, outBuffer.width, outBuffer.height, 8, outBuffer.rowBytes, colorSpace, kCGImageAlphaNoneSkipLast);     
     CGImageRef imageRef = CGBitmapContextCreateImage (ctx); 
     UIImage *returnImage = [UIImage imageWithCGImage:imageRef]; 
     //clean up CGContextRelease(ctx); 
     CGColorSpaceRelease(colorSpace); 
     free(pixelBuffer);
     CFRelease(inBitmapData);
     CGColorSpaceRelease(colorSpace); 
     CGImageRelease(imageRef); 
     return returnImage;
}

Swift

class func boxBlurImage(image: UIImage, withBlurNumber blur: CGFloat) -> UIImage {
    var blur = blur
    if blur < 0.0 || blur > 1.0 {
        blur = 0.5
    }
    var boxSize = Int(blur * 40)
    boxSize = boxSize - (boxSize % 2) + 1

    let img = image.CGImage

    var inBuffer = vImage_Buffer()
    var outBuffer = vImage_Buffer()
    var error: vImage_Error!
    var pixelBuffer: UnsafeMutablePointer!

    // 从CGImage中获取数据
    let inProvider = CGImageGetDataProvider(img)
    let inBitmapData = CGDataProviderCopyData(inProvider)

    // 设置从CGImage获取对象的属性
    inBuffer.width = UInt(CGImageGetWidth(img))
    inBuffer.height = UInt(CGImageGetHeight(img))
    inBuffer.rowBytes = CGImageGetBytesPerRow(img)
    inBuffer.data = UnsafeMutablePointer(CFDataGetBytePtr(inBitmapData))
    pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img))
    if pixelBuffer == nil {
        NSLog("No pixel buffer!")
    }

    outBuffer.data = pixelBuffer
    outBuffer.width = UInt(CGImageGetWidth(img))
    outBuffer.height = UInt(CGImageGetHeight(img))
    outBuffer.rowBytes = CGImageGetBytesPerRow(img)

    error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, nil, 0, 0, UInt32(boxSize), UInt32(boxSize), nil, UInt32(kvImageEdgeExtend))
    if error != nil && error != 0 {
        NSLog("error from convolution %ld", error)
    }

    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let ctx = CGBitmapContextCreate(outBuffer.data, Int(outBuffer.width), Int(outBuffer.height), 8, outBuffer.rowBytes, colorSpace, CGImageAlphaInfo.NoneSkipLast.rawValue)

    let imageRef = CGBitmapContextCreateImage(ctx)!
    let returnImage = UIImage(CGImage: imageRef)

    free(pixelBuffer)

    return returnImage
}

你可能感兴趣的:(图片高斯模糊)