寫(xiě)于2013-04-22
隨著App Store的發(fā)展,越來(lái)越多的應(yīng)用進(jìn)入人們的視野搏熄,只是純粹靠著功能強(qiáng)大來(lái)吃飯的應(yīng)用已經(jīng)跟不上時(shí)代棚唆。排行榜名列前茅的應(yīng)用可能功能并不是最強(qiáng)大的,但絕對(duì)是最吸引眼球的心例∠瑁或者炫目的效果,或者簡(jiǎn)潔清新的風(fēng)格止后,又或者流暢新穎的操作方式瞎惫,這些才能讓你的應(yīng)用足夠“特別”溜腐。
良好的視覺(jué)效果是一款優(yōu)秀應(yīng)用所必備的元素,以往人們覺(jué)得視覺(jué)效果只是美術(shù)設(shè)計(jì)人員的職責(zé)瓜喇,但是隨著iOS SDK的發(fā)展更新挺益,越來(lái)越多簡(jiǎn)便的圖形化API的出現(xiàn),讓程序員自己也能通過(guò)簡(jiǎn)單的幾行代碼實(shí)現(xiàn)美術(shù)人員用PS等軟件才能實(shí)現(xiàn)的效果乘寒,畢竟PS也只是Adobe公司開(kāi)發(fā)的一款軟件而已望众。
在所有視覺(jué)效果里,模糊效果可能是最常用的了。模糊效果一般用來(lái)描述視覺(jué)的層次感,為了突出某個(gè)物體而模糊其背景來(lái)襯托颂碧,或者為了描述物體的動(dòng)態(tài)感等等瘪阁。本文將通過(guò)兩個(gè)圖形框架講解最常用的一種模糊,高斯模糊喳逛。
Core Image
毋庸置疑瞧捌,在iOS提到圖片處理,第一個(gè)想到的就是Core Image框架润文。Core Image框架在iOS5被引進(jìn)SDK姐呐,可用于處理靜態(tài)圖像和視頻,并同時(shí)使用CPU和GPU進(jìn)行處理工作典蝌。Core Image使用過(guò)濾器(fliter)來(lái)處理圖片曙砂,過(guò)濾器是一個(gè)包含圖片處理效果的對(duì)象。處理圖片時(shí)骏掀,只需要將原圖傳給過(guò)濾器鸠澈,過(guò)濾器就會(huì)返回處理后的結(jié)果了。Core Image處理圖片的步驟如下圖所示:
可總結(jié)成以下幾個(gè)步驟:
- 首先創(chuàng)建一個(gè)圖片對(duì)象
CIImage
截驮,然后再創(chuàng)建context對(duì)象CIContext
笑陈。 - 然后獲取所需要的過(guò)濾器。
- 然后將過(guò)濾器綁定到圖片對(duì)象上葵袭。
- 最后涵妥,從過(guò)濾器得到處理結(jié)果,即處理后的圖片坡锡。
一般來(lái)說(shuō)這就是使用Core Image的基本步驟了蓬网。但是需要注意的是,在iOS上并不是文檔里所有的過(guò)濾器都能使用鹉勒,在使用過(guò)濾器之前帆锋,需要先查看其是否支持iOS平臺(tái)。下面就是使用Core Image實(shí)現(xiàn)高斯模糊的代碼實(shí)例:
- (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur {
CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage];
CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"
keysAndValues:kCIInputImageKey, inputImage,
@"inputRadius", @(blur), nil];
CIImage *outputImage = filter.outputImage;
CIContext *context = [CIContext contextWithOptions:nil]; // save it to self.context
CGImageRef outImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
return [UIImage imageWithCGImage:outImage];
}
如果你以為這樣就可以了就錯(cuò)了贸弥,如果當(dāng)你需要使用好幾種過(guò)濾器混合或者需要實(shí)時(shí)的生成模糊效果的話窟坐,你會(huì)發(fā)現(xiàn)Core Image的速度開(kāi)始變慢,有時(shí)慢的無(wú)法使用。所以在使用Core Image時(shí)還需要注意效率問(wèn)題哲鸳,官方文檔總結(jié)了一個(gè)頁(yè)面臣疑,主要是以下幾點(diǎn):
- 不要每次處理的時(shí)候都創(chuàng)建一個(gè)新的
CIContext
,這是因?yàn)槊看蝿?chuàng)建CIContext
幾乎等于為每一個(gè)圖片創(chuàng)建一個(gè)新的OpenGL context徙菠,這樣的開(kāi)銷(xiāo)非常大讯沈。所以創(chuàng)建一個(gè),然后保存起來(lái)婿奔,每次都使用那一個(gè)即可缺狠,查看上面代碼第8行的注釋。 - 合理選擇使用CPU還是GPU萍摊。一般GPU只有在處理視頻時(shí)才具有優(yōu)勢(shì)挤茄,所以一般都使用CPU來(lái)處理。當(dāng)你同時(shí)使用Core Animation或者Core Graphics時(shí)冰木,都會(huì)降低GPU的效率穷劈。如果需要顯式的使用GPU,初始化
CIContext
時(shí)使用contextWithEAGLContext
函數(shù)踊沸。 - 盡量減小圖片的尺寸歇终,并注意不要超過(guò)CPU或GPU能處理的最大尺寸,可查看
inputImageMaximumSize
和outputImageMaximumSize
屬性逼龟。
GPUImage
GPUImage是一個(gè)非常有名的處理圖片和視頻的開(kāi)源庫(kù)评凝。跟Core Image類似,GPUImage也是使用過(guò)濾器的方式來(lái)處理圖片腺律。正如其名奕短,GPUImage幾乎都是使用GPU來(lái)做處理工作,所以和Core Image相比疾渣,GPUImage在視頻處理的優(yōu)勢(shì)非常大篡诽,快了不是一點(diǎn)。即使是圖片處理榴捡,GPUImage也基本上比Core Image的效率更高杈女。
使用GPUImage處理圖片甚至比Core Image更簡(jiǎn)單,只需要將過(guò)濾器賦給圖片對(duì)象即可吊圾,不用考慮context或者設(shè)備等其他問(wèn)題达椰。GPUImage提供了除高斯模糊外的其他幾種不同效果的模糊,雖然Core Image也提供了幾種模糊效果项乒,但目前在iOS上能用的就只有高斯模糊啰劲,而GPUImage可用的有FastBlur
, GaussianBlur
, GaussianSelectiveBlur
和 BoxBlur
。GPUImage還支持自定義的過(guò)濾器檀何,因?yàn)槭情_(kāi)源框架蝇裤。
使用GPUImage實(shí)現(xiàn)模糊效果的代碼如下:
- (UIImage *)blurryGPUImage:(UIImage *)image withBlurLevel:(NSInteger)blur {
GPUImageFastBlurFilter *blurFilter = [[GPUImageFastBlurFilter alloc] init];
blurFilter.blurSize = blur;
UIImage *result = [blurFilter imageByFilteringImage:image];
return result;
}
Core Image vs GPUImage
根據(jù)Core Image和GPUImage的實(shí)際使用效果上看廷支,我得出的結(jié)論是,在不考慮效率問(wèn)題或有特別需求的時(shí)候栓辜,使用Core Image。因?yàn)镃ore Image是iOS自帶框架藕甩,不需要配置直接使用,而且從我實(shí)驗(yàn)高斯模糊的效果上看僵娃,Core Image得到的效果要好于GPUImage,但這并不能說(shuō)明Core Image的效果比GPUImage要好腋妙。
但如果需要實(shí)時(shí)模糊或復(fù)雜效果實(shí)現(xiàn)時(shí)默怨,Core Image的效率就遠(yuǎn)遠(yuǎn)跟不上了,經(jīng)常出現(xiàn)頓卡現(xiàn)象先壕。這時(shí)使用GPUImage說(shuō)不定會(huì)有驚喜谆甜。有人通過(guò)實(shí)驗(yàn)證明GPUImage的效率幾乎全面勝過(guò)Core Image,實(shí)驗(yàn)的工程見(jiàn)BlurCompare集绰。使用GPUImage也非常簡(jiǎn)單规辱,具體請(qǐng)查看其Github主頁(yè)。