iOS開發-圖片高斯模糊效果

iOS開發的時候有的時候須要將圖片設置模糊,或者經過點擊下拉方法,去除模糊,一切都是爲了應用更受用戶歡迎,iOS7以後半透明模糊效果獲得大範圍使用的比較大,如今也能夠看到不少應用局部用到了圖片模糊效果,關於圖片實現高斯模糊效果有三種方式,CoreImage,GPUImage(第三方開源類庫)和vImage。GPUImage沒怎麼用過,本文就講兩種方式Core Image和vImage。html

Core  Image

開始擼代碼以前咱們先來看一下實現的效果:ios

iOS5.0以後就出現了Core Image的API,Core Image的API被放在CoreImage.framework庫中,在iOS和OS X平臺上,Core Image都提供了大量的濾鏡(Filter),在OS X上有120多種Filter,而在iOS上也有90多。首先咱們擴展一下UIImage,添加類方法:git

+(UIImage *)coreBlurImage:(UIImage *)image
           withBlurNumber:(CGFloat)blur {
    //博客園-FlyElephant
    CIContext *context = [CIContext contextWithOptions:nil];
    CIImage  *inputImage=[CIImage imageWithCGImage:image.CGImage];
    //設置filter
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [filter setValue:inputImage forKey:kCIInputImageKey];
    [filter setValue:@(blur) forKey: @"inputRadius"];
    //模糊圖片
    CIImage *result=[filter valueForKey:kCIOutputImageKey];
    CGImageRef outImage=[context createCGImage:result fromRect:[result extent]];
    UIImage *blurImage=[UIImage imageWithCGImage:outImage];
    CGImageRelease(outImage);
    return blurImage;
}

其中過濾的選項設置爲高斯模糊:github

  

vImage 方式

vImage屬於Accelerate.Framework,須要導入Accelerate下的Accelerate頭文件,Accelerate主要是用來作數字信號處理、圖像處理相關的向量、矩陣運算的庫。圖像能夠認爲是由向量或者矩陣數據構成的,Accelerate裏既然提供了高效的數學運算API,天然就能方便咱們對圖像作各類各樣的處理,模糊算法使用的是vImageBoxConvolve_ARGB8888這個函數。 算法

+(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;
}

圖片模糊調用:app

    self.imageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 300, SCREENWIDTH, 100)];
    self.imageView.contentMode=UIViewContentModeScaleAspectFill;
    self.imageView.image=[UIImage boxblurImage:self.image withBlurNumber:0.5];
    self.imageView.clipsToBounds=YES;
    [self.view addSubview:self.imageView];

關於兩種方式的選擇的建議ide

效果:第一種Core Image設置模糊以後會在周圍產生白邊,vImage使用不存在任何問題;函數

性能:圖像模糊處理屬於複雜的計算,大部分圖片模糊選擇的是vImage,性能最佳(沒有親自測試過,有興趣能夠本身測試)性能

項目地址:https://github.com/SmallElephant/iOS-UIImageBoxBlur測試

參考資料:https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CIGaussianBlur

相關文章
相關標籤/搜索