1. 程式人生 > >iOS 模糊效果實現

iOS 模糊效果實現

iOS的模糊效果實現方法有好幾種,基本分為兩種方式,一種是將圖片進行模糊,一種是將模糊的控制元件放在UI介面上,使控制元件覆蓋的區域達到模糊的效果。每種方式我各選了2種方法,下面介紹一下它們的實現方式以及對比一下它們的優缺點。


螢幕快照 2016-07-29 上午10.10.32.png
coreImage

該方法實現的模糊效果較好,模糊程度的可調範圍很大,可以根據實際的需求隨意除錯。缺點就是耗時,我在模擬器上跑需要1-2秒的時間,所有該方法需要放在子執行緒中執行。

dispatch_async(dispatch_get_global_queue(0, 0), ^{
        CIContext *context = [CIContext contextWithOptions:nil];
        CIImage *ciImage = [CIImage imageWithCGImage:image.CGImage];
        CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
        [filter setValue:ciImage forKey:kCIInputImageKey];
        //設定模糊程度
        [filter setValue:@30.0f forKey: @"inputRadius"];
        CIImage *result = [filter valueForKey:kCIOutputImageKey];
        CGRect frame = [ciImage extent];
        NSLog(@"%f,%f,%f,%f",frame.origin.x,frame.origin.y,frame.size.width,frame.size.height);
        CGImageRef outImage = [context createCGImage: result fromRect:ciImage.extent];
        UIImage * blurImage = [UIImage imageWithCGImage:outImage];
        dispatch_async(dispatch_get_main_queue(), ^{
            coreImgv.image = blurImage;
        });
    });
vImage

該方法效率高,但是模糊程度最大隻能達到上圖展示的程度,而且我在使用它對網路載入的圖片進行模糊時,整個圖片會變紅。

//使用前需要匯入標頭檔案
#import <Accelerate/Accelerate.h>
+ (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;
}

下面兩種方法實現起來都很簡單,但是隻有幾種系統提供的樣式可選。
BlurEffect是在iOS8之後才出現的,它和toolbar實現的效果基本一樣,比toolbar多了一種顏色更深的樣式,如上面大圖所示。

BlurEffect
UIImageView *blurImgv = [[UIImageView alloc]initWithFrame:CGRectMake(50, 500, 150, 150)];
blurImgv.image = image;
[self.view addSubview:blurImgv];
UIBlurEffect *beffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *view = [[UIVisualEffectView alloc]initWithEffect:beffect];
view.frame = blurImgv.frame;
[self.view addSubview:view];
toolbar
UIImageView *toolImgv = [[UIImageView alloc]initWithFrame:CGRectMake(210, 500, 150, 150)];
toolImgv.image = image;
[self.view addSubview:toolImgv];
UIToolbar *toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(210, 500, 150, 150)];
toolBar.barStyle = UIBarStyleDefault;
[self.view addSubview:toolBar];

上面介紹了四種實現模糊效果的方法,同時也進行了簡單的比較。具體的使用還是要根據專案的需求選擇最合適的方法。