iOS 模糊效果實現
阿新 • • 發佈:2019-01-04
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];
上面介紹了四種實現模糊效果的方法,同時也進行了簡單的比較。具體的使用還是要根據專案的需求選擇最合適的方法。