【iOS】 一個(gè)模糊(毛玻璃)效果引發(fā)的探索

劇情介紹

在iOS開發(fā)中夺脾,經(jīng)常會(huì)看到毛玻璃效果有鹿,也叫模糊效果鼓黔,比如系統(tǒng)的通知中心央勒,這個(gè)很時(shí)髦的效果增加了美觀性。


通知中心的模糊效果

查看資料發(fā)現(xiàn)實(shí)現(xiàn)毛玻璃效果有很多種方式澳化,下面總結(jié)了其中幾種方式崔步。

靜態(tài)模糊效果
  • 對(duì)于靜態(tài)的模糊效果,最直接的方式就是加載做好的模糊圖片
動(dòng)態(tài)模糊效果
  • 蘋果原生控件:UIVisualEffectView
  • 蘋果原生API:Core Image 的濾鏡效果
  • 蘋果原生API:vImage
  • 使用第三方工具GPUImage
  • 使用第三方工具FXBlurView
  • ...

一缎谷、蘋果原生控件:UIVisualEffectView實(shí)現(xiàn)模糊效果

  • UIVisualEffectView是iOS8的新特性井濒,該控件主要用于為原有的控件增加模糊效果。
  • 由于是iOS8的新特性列林,所以具有一定的局限性瑞你。
  • UIVisualEffectView繼承自UIView,沒有繼承UIControl希痴,所以只能做靜態(tài)控件使用者甲。
  • 控制UIVisualEffectView控件模糊效果的屬性時(shí)effect只讀屬性,該屬性的類型是UIVisualEffect,該類型有兩個(gè)子類:UIBlurEffectUIVibrancyEffect润梯。
  • UIBlurEffect允許應(yīng)用程序中動(dòng)態(tài)的創(chuàng)建實(shí)時(shí)的模糊效果过牙;UIVibrancyEffect允許在模糊效果上“寫字”。
  • Blur Style有三種效果:
    • UIBlurEffectStyleLight:白色的模糊效果纺铭。
    • UIBlurEffectStyleExtraLight:極亮的白色模糊效果寇钉。
    • UIBlurEffectStyleDark:暗色的模糊效果。
  • 可以通過(guò)在Interface Bulider中將UIVibrancyEffect控件直接拖入某個(gè)控件內(nèi)添加模糊效果舶赔,也可以通過(guò)純代碼的形式創(chuàng)建和添加扫倡。
    // UIBlurEffectStyleLight模式
    UIVisualEffectView *lightView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
    lightView.frame = CGRectMake(40, 40, 300, 100);
    [self.imageView addSubview:lightView];
    
    // UIBlurEffectStyleExtraLight模式
    UIVisualEffectView *extraLightView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight]];
    extraLightView.frame = CGRectMake(40, 160, 300, 100);
    [self.imageView addSubview:extraLightView];
    
    // UIBlurEffectStyleDark
    UIVisualEffectView *darkView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
    darkView.frame = CGRectMake(40, 280, 300, 100);
    [self.imageView addSubview:darkView];

二、Core Image 的濾鏡效果實(shí)現(xiàn)模糊效果

  • 在iOS5.0之后Core Image 的API提供了大量的濾鏡(Filter)效果。
  • 利用Core Image 實(shí)現(xiàn)模糊效果非常簡(jiǎn)單撵溃,只需要10行左右的代碼就能搞定疚鲤。
  • 使用Core Image 設(shè)置模糊之后,會(huì)在周圍產(chǎn)生白邊缘挑。
  • 代碼中的CIGaussianBlur是一個(gè)濾鏡名稱集歇,更多的濾鏡可以參考蘋果濾鏡列表
  • Core Image實(shí)現(xiàn)高斯模糊的原理是:將原來(lái)的圖片驚醒模糊處理返回渲染后的一整張圖片,比較消耗CPU性能语淘。
/**
 * 使用Core Image進(jìn)行模糊
 */
- (UIImage *)blurryImage:(UIImage *)image withblurLevel:(CGFloat)blur{
    
    // 1.創(chuàng)建CIImage
    CIImage * ciImage = [[CIImage alloc]initWithImage:image];
    
    // 2.添加濾鏡
    CIFilter * blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
    
    // 3.將圖片輸入到濾鏡中
    [blurFilter setValue:ciImage forKey:kCIInputImageKey];
    
    // 4.設(shè)置模糊值(不模糊為0诲宇,模糊最大為100)
    [blurFilter setValue:[NSNumber numberWithFloat:blur] forKey:@"inputRadius"];
    
    // 5.將處理好的圖片輸出
    CIImage * outCiImage = [blurFilter valueForKey:kCIOutputImageKey];

    // 6.生成圖片 CIContext(CIImage的操作句柄)nil表示默認(rèn)有CPU渲染圖片(如果讓GPU渲染提高效率,則應(yīng)設(shè)置contextWithOptions的字典數(shù)據(jù))
    CIContext * context = [CIContext contextWithOptions:nil];
    
    // 7.獲取CIImage句柄
    CGImageRef outCGImage = [context createCGImage:outCiImage fromRect:[outCiImage extent]];
    
    // 8.最終獲取到圖片
    UIImage * blurImage = [UIImage imageWithCGImage:outCGImage];
    
    // 9.釋放句柄
    CGImageRelease(outCGImage);
    
    return blurImage;
}
Core Image實(shí)現(xiàn)高斯模糊

三惶翻、使用vImage實(shí)現(xiàn)高斯模糊

  • vImage屬于Accelerate.Framework姑蓝,所以在使用是需要導(dǎo)入Accelerate頭文件,導(dǎo)入頭文件代碼:#import <Accelerate/Accelerate.h>
  • Accelerate主要用來(lái)做數(shù)圖像處理、字信號(hào)處理相關(guān)的向量吕粗、矩陣運(yùn)算的庫(kù)纺荧。
  • 圖像可以認(rèn)為是由向量后者矩陣數(shù)據(jù)構(gòu)成的。
  • Accelerate提供了搞笑的數(shù)學(xué)運(yùn)算API颅筋,所以能對(duì)圖像做各種各樣的處理宙暇。
  • Accelerate實(shí)現(xiàn)高斯模糊的原理是:將原來(lái)的圖片驚醒模糊處理返回渲染后的一整張圖片,比較消耗CPU垃沦。
  • 模糊算法使用的函數(shù)是:vImageBoxConvolve_ARGB8888
代碼

(記得先導(dǎo)入頭文件#import <Accelerate/Accelerate.h>)

/**
 * 使用vImage實(shí)現(xiàn)模糊效果
 */
- (UIImage *)blurryImage:(UIImage *)image withblur:(CGFloat)blur{
    
    if (blur < 0.f || blur > 1.0f) blur = 0.5f;
    
    int boxSize = (int)(blur * 100);
    boxSize -=(boxSize % 2) + 1;
    
    // 圖像處理
    CGImageRef img = image.CGImage;
    
    // 輸入緩存 輸出緩存
    vImage_Buffer inBuffer,outBuffer;
    
    vImage_Error error;
    
    // 像素緩存
    void * pixelBuffer;
    
    //數(shù)據(jù)源提供者客给,Defines an opaque type that supplies Quartz with data.
    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    // provider’s data.
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
    
    //寬,高肢簿,字節(jié)/行,data
    inBuffer.width = CGImageGetWidth(img);
    inBuffer.height = CGImageGetHeight(img);
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);
    inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
    
    //像數(shù)緩存蜻拨,字節(jié)行*圖片高
    pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
    outBuffer.data = pixelBuffer;
    outBuffer.width = CGImageGetWidth(img);
    outBuffer.height = CGImageGetHeight(img);
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);
    
    // 第三個(gè)中間的緩存區(qū),抗鋸齒的效果
    void *pixelBuffer2 = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
    vImage_Buffer outBuffer2;
    outBuffer2.data = pixelBuffer2;
    outBuffer2.width = CGImageGetWidth(img);
    outBuffer2.height = CGImageGetHeight(img);
    outBuffer2.rowBytes = CGImageGetBytesPerRow(img);
    //Convolves a region of interest within an ARGB8888 source image by an implicit M x N kernel that has the effect of a box filter.
    error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer2, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
    error = vImageBoxConvolve_ARGB8888(&outBuffer2, &inBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
    error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
    
    if (error) NSLog(@"error from convolution %ld", error);
    
    //    NSLog(@"字節(jié)組成部分:%zu",CGImageGetBitsPerComponent(img));
    
    //顏色空間DeviceRGB
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    //用圖片創(chuàng)建上下文,CGImageGetBitsPerComponent(img),7,8
    CGContextRef ctx = CGBitmapContextCreate(
                                             outBuffer.data,
                                             outBuffer.width,
                                             outBuffer.height,
                                             8,
                                             outBuffer.rowBytes,
                                             colorSpace,
                                             CGImageGetBitmapInfo(image.CGImage));
    
    //根據(jù)上下文池充,處理過(guò)的圖片,重新組件
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
    UIImage * outImage = [UIImage imageWithCGImage:imageRef];
    
    //clean up
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);
    free(pixelBuffer);
    free(pixelBuffer2);
    CFRelease(inBitmapData);
    
    //CGColorSpaceRelease(colorSpace);   //多余的釋放
    
    // 釋放句柄
    CGImageRelease(imageRef);

    return outImage;
}
使用vImage實(shí)現(xiàn)高斯模糊

四缎讼、使用第三方工具GPUImage實(shí)現(xiàn)高斯模糊

  • GPUImage一個(gè)基于GPU圖像和視頻處理的開源框架收夸,適用面廣。
  • GPUImage同時(shí)支持objective-C和Swift血崭。
  • GPUImage的github地址GPUImage
  • GPUImage可以直接導(dǎo)入本地卧惜,也可以使用使用pod導(dǎo)入。這是使用pod比較簡(jiǎn)單夹纫。
  • 使用GPUImage實(shí)現(xiàn)高斯模糊的代碼非常簡(jiǎn)單.
/**
 *使用GPUImage實(shí)現(xiàn)高斯模糊
 */
- (UIImage *)blurryGPUImage:(UIImage *)image withBlurLevel:(CGFloat)blur{
    
    GPUImageGaussianBlurFilter * blurFilter = [[GPUImageGaussianBlurFilter alloc]init];
    blurFilter.blurRadiusInPixels = blur;
    UIImage * blurImage = [blurFilter imageByFilteringImage:image];
    
    return blurImage;
}
使用第三方工具GPUImage實(shí)現(xiàn)高斯模糊

五咽瓷、 使用第三方工具FXBlurView實(shí)現(xiàn)高斯模糊

  • FXBlurViewUIView的子類,支持iOS5.0及其以上
  • FXBlurView的特點(diǎn)是簡(jiǎn)單和輕快舰讹,看源碼就知道幾行代碼就可以搞定茅姜。
  • FXBlurView有兩種模式:static靜態(tài)模糊,也就是只模糊一次月匣,就算背景圖片改變了模糊效果也不會(huì)改變钻洒;dynamic動(dòng)態(tài)模糊奋姿,也就是會(huì)實(shí)時(shí)的對(duì)背景圖片進(jìn)行模糊,是會(huì)不斷變化的素标。
  • FXBlurView同樣也可以通過(guò)pod導(dǎo)入称诗。
  • FXBlurView的原理是在圖片上添加一個(gè)FXBlurView的對(duì)象覆蓋原圖。
    // 設(shè)置模糊效果
    FXBlurView * blurView = [[FXBlurView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 200)];
    blurView.backgroundColor = [UIColor whiteColor];
    
    // 設(shè)置模式
    blurView.dynamic = YES;
    // 設(shè)置模糊半徑
    blurView.blurRadius = 10.0;
使用第三方工具FXBlurView實(shí)現(xiàn)高斯模糊

demo后續(xù)上傳

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末头遭,一起剝皮案震驚了整個(gè)濱河市寓免,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌任岸,老刑警劉巖再榄,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異享潜,居然都是意外死亡困鸥,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門剑按,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)疾就,“玉大人,你說(shuō)我怎么就攤上這事艺蝴♀” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵猜敢,是天一觀的道長(zhǎng)姑荷。 經(jīng)常有香客問我,道長(zhǎng)缩擂,這世上最難降的妖魔是什么鼠冕? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮胯盯,結(jié)果婚禮上懈费,老公的妹妹穿的比我還像新娘。我一直安慰自己博脑,他們只是感情好憎乙,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著叉趣,像睡著了一般泞边。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上君账,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天繁堡,我揣著相機(jī)與錄音,去河邊找鬼。 笑死椭蹄,一個(gè)胖子當(dāng)著我的面吹牛闻牡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播绳矩,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼罩润,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了翼馆?” 一聲冷哼從身側(cè)響起割以,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎应媚,沒想到半個(gè)月后严沥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡中姜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年消玄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丢胚。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡翩瓜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出携龟,到底是詐尸還是另有隱情兔跌,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布峡蟋,位于F島的核電站坟桅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蕊蝗。R本人自食惡果不足惜桦卒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匿又。 院中可真熱鬧,春花似錦建蹄、人聲如沸碌更。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)痛单。三九已至,卻和暖如春劲腿,著一層夾襖步出監(jiān)牢的瞬間旭绒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挥吵,地道東北人重父。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像忽匈,于是被迫代替她去往敵國(guó)和親房午。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • iOS開發(fā)中有的時(shí)候需要將圖片設(shè)置模糊丹允,來(lái)實(shí)現(xiàn)特定的效果獲取更好的用戶體驗(yàn), iOS7之后半透明模糊效果得到大范圍...
    零距離仰望星空閱讀 46,504評(píng)論 47 223
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)郭厌、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,058評(píng)論 4 62
  • iOS7后雕蔽,半透明模糊效果得到了廣泛的使用折柠,所以iOS開發(fā)過(guò)程中經(jīng)常需要用到半透明模糊效果,本文對(duì)比列舉幾種實(shí)現(xiàn)半...
    乒什么乓閱讀 27,970評(píng)論 18 85
  • 目前不想生娃的原因就是批狐,這個(gè)社會(huì)對(duì)媽媽的期望值太高扇售。能掙錢,會(huì)做飯贾陷,能打掃家務(wù)缘眶,會(huì)保健,還得懂自我成長(zhǎng)髓废,還得不能成...
    酸爽的橙子閱讀 365評(píng)論 0 0
  • 1 當(dāng)你看到同學(xué)們都多才多藝的時(shí)候频伤,你覺得自己什么都不會(huì)恳谎! 當(dāng)你看到同學(xué)們與人相處非常愉快的時(shí)候,你覺得自己和誰(shuí)都...
    萌點(diǎn)點(diǎn)閱讀 1,034評(píng)論 2 0