天天看點

iOS開發探索-高斯模糊&毛玻璃效果

原文位址:http://www.jianshu.com/p/6dd0eab888a6

iOS開發中有的時候需要将圖檔設定模糊,來實作特定的效果擷取更好的使用者體驗, iOS7之後半透明模糊效果得到大範圍使用的比較大,現在也可以看到很多應用局部用到了圖檔模糊效果,可以通過高斯模糊和毛玻璃效果達到圖檔模糊效果。

iOS開發探索-高斯模糊&毛玻璃效果

左邊玻璃右邊模糊

高斯模糊效果

1. CoreImage:

iOS5.0之後就出現了Core Image的API,Core Image的API被放在CoreImage.framework庫中, 在iOS和OS X平台上,Core Image都提供了大量的濾鏡(Filter),在OS X上有120多種Filter,而在iOS上也有90多。

+(UIImage *)coreBlurImage:(UIImage *)image withBlurNumber:(CGFloat)blur 
{ 
    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;
}
           

2. vImage

vImage屬于Accelerate.Framework,需要導入 Accelerate下的 Accelerate頭檔案, Accelerate主要是用來做數字信号處理、圖像處理相關的向量、矩陣運算的庫。圖像可以認為是由向量或者矩陣資料構成的,Accelerate裡既然提供了高效的數學運算API,自然就能友善我們對圖像做各種各樣的處理 ,模糊算法使用的是vImageBoxConvolve_ARGB8888這個函數。

+(UIImage *)boxblurImage:(UIImage *)image withBlurNumber:(CGFloat)blur
 { 
     if (blur < f || blur > f) {
        blur = f; 
     }
     int boxSize = (int)(blur * );
     boxSize = boxSize - (boxSize % ) + ; 
     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, , , boxSize, boxSize, NULL, kvImageEdgeExtend);
     if (error) { 
           NSLog(@"error from convolution %ld", error); 
     } 
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
     CGContextRef ctx = CGBitmapContextCreate( outBuffer.data, outBuffer.width, outBuffer.height, , 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;
}
           
方法調用
UIImageView  *imageView=[[UIImageView alloc]initWithFrame:CGRectMake(, , SCREENWIDTH, )]; 
imageView.contentMode=UIViewContentModeScaleAspectFill;
imageView.image=[UIImage boxblurImage:image withBlurNumber:]; 
imageView.clipsToBounds=YES;
[self.view addSubview:imageView];
           

3.GPUImage

GPUImage是用裝置的GPU來實時處理圖檔,給圖檔加各種濾鏡效果的一個開源庫。

可以實時地給照相機加上濾鏡效果,很多App都支援這種實時濾鏡。

連結位址:https://github.com/BradLarson/GPUImage

差別:

效果:第一種Core Image設定模糊之後會在周圍産生白邊,vImage使用不存在任何問題;

性能:圖像模糊處理屬于複雜的計算,大部分圖檔模糊選擇的是vImage,性能最佳

項目位址: https://github.com/524429264/iOS-UIImageBoxBlur

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

毛玻璃效果
  1. 蘋果在iOS7.0之後,很多系統界面都使用了毛玻璃效果,增加了界面的美觀性,比如通知中心界面;其實在iOS7.0(包括)之前還是有系統的類可以實作毛玻璃效果的, 就是 UIToolbar這個類
    iOS7
    毛玻璃的樣式(枚舉)
    UIBarStyleDefault          = ,
    UIBarStyleBlack            = ,
    UIBarStyleBlackOpaque      = , // Deprecated. Use UIBarStyleBlack
    UIBarStyleBlackTranslucent = , // Deprecated. Use UIBarStyleBlack and set the translucent property to YES
    
    UIImageView *bgImgView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    bgImgView.image = [UIImage imageNamed:@"huoying4.jpg"];
    [self.view addSubview:bgImgView];
    
    UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(, , bgImgView.frame.size.width*, bgImgView.frame.size.height)];
    toolbar.barStyle = UIBarStyleBlackTranslucent;
    [bgImgView addSubview:toolbar];
               
  2. 在iOS8.0之後,蘋果新增了一個類UIVisualEffectView,通過這個類來實作毛玻璃效果與上面的UIToolbar一樣,而且效率也非常之高,使用也是非常簡單,幾行代碼搞定. UIVisualEffectView是一個抽象類,不能直接使用,需通過它下面的三個子類來實作(UIBlurEffect, UIVisualEffevt, UIVisualEffectView);

    子類UIBlurEffect隻有一個類方法,用來快速建立一個毛玻璃效果,參數是一個枚舉,用來設定毛玻璃的樣式,而UIVisualEffectView則多了兩個屬性和兩個構造方法,用來快速将建立的毛玻璃添加到這個UIVisualEffectView上.

    特别注意: 這個類是iOS8.0之後才适用, 是以如果項目要相容iOS7.0的話, 還是要考慮其它的兩種方法了.

實作代碼:

同樣是先快速的執行個體化UIBlurEffect并設定毛玻璃的樣式,然後再通過UIVisualEffectView的構造方法将UIBlurEffect的執行個體添加上去, 最後設定frame或者是通過添加限制, 将effectView添加到要實作了毛玻璃的效果的view控件上,效果圖和上面的一樣.

iOS8
 毛玻璃的樣式(枚舉)
 UIBlurEffectStyleExtraLight,
 UIBlurEffectStyleLight,
 UIBlurEffectStyleDark

 UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
 UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
 effectView.frame = CGRectMake(, , bgImgView.frame.size.width*, bgImgView.frame.size.height);
 [bgImgView addSubview:effectView];
           
項目位址:https://github.com/524429264/EffectViewDemo

文/零距離仰望星空(簡書作者)

原文連結:http://www.jianshu.com/p/6dd0eab888a6

著作權歸作者所有,轉載請聯系作者獲得授權,并标注“簡書作者”。

繼續閱讀