iOS 開發之模糊效果的五種實現
前言
在iOS開發中我們經常會用到模糊效果使我們的介面更加美觀,而iOS本身也提供了幾種達到模糊效果的API,如:Core Image,使用Accelerate.Framework中的vImage API,在iOS 7之前系統的類提供UIToolbar,在iOS 8之後蘋果新增加的一個類UIVisualEffectView;另外也有一些牛人寫的第三方框架,如:GPUImage。本篇就針對這五種方式講解一下具體的實現。
正文
下面就按照這五種方式,將其實現模糊效果的具體實現一一講解一下:
- 在iOS 7之前系統的類提供UIToolbar來實現毛玻璃效果:
- (void)toolbarStyle{
CGRect toolbarRect = CGRectMake(0, 0,ScreenW/2,ScreenH);
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:toolbarRect];
/*
* UIBarStyleDefault = 0,
* UIBarStyleBlack = 1,
* UIBarStyleBlackOpaque = 1, // Deprecated. Use UIBarStyleBlack
* UIBarStyleBlackTranslucent = 2, // Deprecated. Use UIBarStyleBlack and set the translucent property to YES
*/
toolbar.barStyle = UIBarStyleBlack;
[self.myImageView addSubview:toolbar];
}
- 在iOS 8之後蘋果新增加了一個類UIVisualEffectView,通過這個類來實現毛玻璃效果:
- (void)uivisualEffectViewStyle{
/* NS_ENUM_AVAILABLE_IOS(8_0)
* UIBlurEffectStyleExtraLight,//額外亮度,(高亮風格)
* UIBlurEffectStyleLight,//亮風格
* UIBlurEffectStyleDark,//暗風格
* UIBlurEffectStyleExtraDark __TVOS_AVAILABLE(10_0) __IOS_PROHIBITED __WATCHOS_PROHIBITED,
* UIBlurEffectStyleRegular NS_ENUM_AVAILABLE_IOS(10_0), // Adapts to user interface style
* UIBlurEffectStyleProminent NS_ENUM_AVAILABLE_IOS(10_0), // Adapts to user interface style
*/
//實現模糊效果
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
//毛玻璃檢視
UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];;
effectView.frame = CGRectMake(0, 0, ScreenW/2, ScreenH);
[self.myImageView addSubview:effectView];
}
- iOS5.0之後就出現了Core Image的API,Core Image的API被放在CoreImage.framework庫中, 在iOS和OS X平臺上,Core Image都提供了大量的濾鏡(Filter),在OS X上有120多種Filter,而在iOS上也有90多,Core Image設定模糊之後會在周圍產生白邊:
- (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;
}
- GPUImage的開源庫實現毛玻璃效果:
- (UIImage *)GPUImageStyleWithImage:(UIImage *)image{
GPUImageGaussianBlurFilter *filter = [[GPUImageGaussianBlurFilter alloc] init];
filter.blurRadiusInPixels = 10.0;//值越大,模糊度越大
UIImage *blurImage = [filter imageByFilteringImage:image];
return blurImage;
}
- 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;
}
原始碼已上傳至fenglinyunshi-git,歡迎下載,並提出寶貴意見。
結語
- UIVisualEffectView技術是從iOS8之後引進的,原理是在圖片上方生成一個蒙層,若最低適配iOS8的話可以考慮採取這個,運用UIBlurEffect是可逆的,我們可以去掉蒙層,顯示圖片;
[effectview removeFromSuperview];
- iOS 7之前系統的類提供的UIToolbar,原理也是在圖片上方生成一個蒙層。
- 利用CoreImage 進行模糊處理,是非常消耗CPU效能的;
- GPUImage的開源庫實現毛玻璃效果也比較吃記憶體,相對Core Image好一點;
- 影象模糊處理屬於複雜的計算,大部分圖片模糊選擇的是vImage,效能最佳。
UIToolbar和UIBlurEffect都是在圖片上方生成一個蒙層,都可以設定模糊的範圍;而其他三種方式都是對原來的圖片進行模糊處理返回渲染後的一整張圖片,相對來說比較耗效能。圖1-2 是實測五種方式的記憶體佔用:
一月不讀書,耳目失精爽。
相關文章
- iOS中實現模糊效果教程iOS
- iOS開發使用半透明模糊效果iOS
- iOS 開發使用半透明模糊效果iOS
- iOS 開發中如何使用半透明模糊效果iOS
- 玩轉iOS開發 - 簡易的實現2種抽屜效果iOS
- 圖片模糊效果實現(RenderScript)
- SVG實現動態模糊動畫效果SVG動畫
- SVG 實現動態模糊動畫效果SVG動畫
- iOS開發筆記(五):UIScrollView實現原理iOS筆記UIView
- Android開發之DrawerLayout實現抽屜效果Android
- 巧用模糊實現視覺的 3D 效果視覺3D
- iOS開發之微信聊天頁面實現iOS
- iOS全景效果實現iOS
- IOS抽屜效果的實現iOS
- IOS8模糊毛玻璃的效果UIVisualEffectViewiOSUIView
- iOS開發中陣列常用的五種遍歷方式iOS陣列
- iOS專案開發實戰——使用CALayer實現圖片的淡入淡出效果iOS
- 記錄三種實現圖片模糊的方法
- iOS開發UI篇--使用UICollectionView實現一個傾斜列表效果iOSUIView
- Vue開發——實現吸頂效果Vue
- Android開發之TextView文字水平滾動效果實現AndroidTextView
- 基於ArkUI框架開發——圖片模糊處理的實現UI框架
- 直播軟體開發,實現模糊搜尋的程式碼分析
- iOS開發UI篇--使用UICollectionView實現一個列表頭部拉伸效果的案例iOSUIView
- iOS開發中動畫之點贊圖示放大效果iOS動畫
- iOS專案開發實戰——檢視動畫效果iOS動畫
- iOS開發-探索scrollView的實現iOSView
- 小程式雲開發模糊查詢,實現資料庫多欄位的模糊搜尋資料庫
- iOS 類知乎”分頁”效果的實現?iOS
- iOS開發之SQLite–C語言介面規範(五):iOS開發使用SQLite例項iOSSQLiteC語言
- Android開發中陰影效果的實現Android
- iOS開發之TabBar再次點選實現重新整理iOStabBar
- iOS開發之UITableView聯動實現城市選擇器iOSUIView
- HarmonyOS NEXT應用開發之圖片縮放效果實現
- iOS開發之tableView左滑刪除的兩種方法iOSView
- 原生JS實現拋物線動畫以及動態模糊效果JS動畫
- iOS開發-清理快取功能的實現iOS快取
- iOS開發UIScrollView的底層實現iOSUIView