前言
最近在研究 Core Image 自定義 Filter 相關(guān)內(nèi)容,重新學(xué)習(xí)了 Core Image,對(duì) Core Image 的一些優(yōu)化點(diǎn)也有了一定的了解。故此記錄,與君交流~
本文將會(huì)介紹逐一介紹 Core Image 相關(guān)基礎(chǔ)概念、使用方式、注意點(diǎn)以及和其他圖像處理方案的對(duì)比。也算是下一篇文章:Core Image 自定義 Filter~的預(yù)備知識(shí),畢竟只有了解了 Core Image 的作用以及它的優(yōu)勢(shì),才有學(xué)習(xí)自定義 Filter 的動(dòng)力。
現(xiàn)在,開始吧~
Core Image 是 iOS5 新加入到 iOS 平臺(tái)的一個(gè)圖像處理框架,提供了強(qiáng)大高效的圖像處理功能, 用來(lái)對(duì)基于像素的圖像進(jìn)行操作與分析, 內(nèi)置了很多強(qiáng)大的濾鏡(Filter) (目前數(shù)量超過了180種), 這些Filter 提供了各種各樣的效果, 并且還可以通過濾鏡鏈將各種效果的Filter疊加起來(lái)形成強(qiáng)大的自定義效果。
一個(gè)濾鏡是一個(gè)對(duì)象,有很多輸入和輸出,并執(zhí)行一些變換。例如,模糊濾鏡可能需要輸入圖像和一個(gè)模糊半徑來(lái)產(chǎn)生適當(dāng)?shù)哪:蟮妮敵鰣D像。
一個(gè)濾鏡鏈是一個(gè)鏈接在一起的濾鏡網(wǎng)絡(luò),使得一個(gè)濾鏡的輸出可以是另一個(gè)濾鏡的輸入。以這種方式,可以實(shí)現(xiàn)精心制作的效果。
iOS8 之后更是支持自定義 CIFilter,可以定制滿足業(yè)務(wù)需求的復(fù)雜效果。
Core Image is an image processing and analysis technology designed to provide near real-time processing for still and video images. It operates on image data types from the Core Graphics, Core Video, and Image I/O frameworks, using either a GPU or CPU rendering path. Core Image hides the details of low-level graphics processing by providing an easy-to-use application programming interface (API). You don’t need to know the details of OpenGL or OpenGL ES to leverage the power of the GPU, nor do you need to know anything about Grand Central Dispatch (GCD) to get the benefit of multicore processing. Core Image handles the details for you.
這是蘋果官方文檔對(duì)于 Core Image 的介紹,大致意思是:Core Image 是一種為靜態(tài)圖像和 Video 提供處理和分析的技術(shù),它可以使用 GPU/CPU 的方式對(duì)圖像進(jìn)行處理。Core Image 提供了簡(jiǎn)潔的 API 給用戶,隱藏了圖像處理中復(fù)雜的底層內(nèi)容。你可以在不了解 OpenGL、OpenGL ES 甚至是 GCD 的基礎(chǔ)上對(duì)其進(jìn)行使用,他已經(jīng)幫你對(duì)這些復(fù)雜的內(nèi)容進(jìn)行處理了。
廢話這么多,蘋果就想告訴我們一件事:所有的底層細(xì)節(jié)他都幫你做好了,你只需要放心調(diào)用API就行了。
這就是 Core Image 的基礎(chǔ)概念,比較簡(jiǎn)短,正如它的使用方式一樣簡(jiǎn)潔。
然而在我個(gè)人學(xué)習(xí)過程中,我有一種強(qiáng)烈的感覺:Apple 很重視 Core Image,Core Image 一定會(huì)越來(lái)越棒。
每年的 WWDC Session 中,都有提及 Core Image 的相關(guān)優(yōu)化。
從最初的幾十種內(nèi)置濾鏡到如今的180多種。
從最初只支持 macOS,到如今也支持 iOS。
iOS8 之后支持自定義 Filter。
iOS8 增強(qiáng) GPU 渲染,在后臺(tái)也能繼續(xù)使用 GPU 進(jìn)行處理。
引入 CIDetector,提供一些常用的圖片識(shí)別功能。包括人臉識(shí)別、條形碼識(shí)別、文本識(shí)別等。
與越來(lái)越多的框架相結(jié)合:OpenGLES,PhotoExtension,SceneKit,SpriteKit,Metal。
iOS 10之后,支持對(duì)原生 RAW 格式圖片的處理。
So,它真的值得學(xué)習(xí)!
這里我們從它的基礎(chǔ) API 介紹起。
Core Image 的 API 主要就是三類:
CIImage 保存圖像數(shù)據(jù)的類,可以通過UIImage,圖像文件或者像素?cái)?shù)據(jù)來(lái)創(chuàng)建,包括未處理的像素?cái)?shù)據(jù)。
CIFilter 表示應(yīng)用的濾鏡,這個(gè)框架中對(duì)圖片屬性進(jìn)行細(xì)節(jié)處理的類。它對(duì)所有的像素進(jìn)行操作,用一些鍵-值設(shè)置來(lái)決定具體操作的程度。
CIContext 表示上下文,如 Core Graphics 以及 Core Data 中的上下文用于處理繪制渲染以及處理托管對(duì)象一樣,Core Image 的上下文也是實(shí)現(xiàn)對(duì)圖像處理的具體對(duì)象。可以從其中取得圖片的信息。
至于使用,相當(dāng)?shù)姆奖恪?/p>
下面以 “動(dòng)態(tài)模糊” 舉例,我們使用系統(tǒng)提供的CIMotionBlur來(lái)實(shí)現(xiàn)。
//傳入濾鏡名稱(e.g. @"CIMotionBlur"), 輸出處理后的圖片- (UIImage*)outputImageWithFilterName:(NSString*)filterName {//1. 將UIImage轉(zhuǎn)換成CIImageCIImage*ciImage = [[CIImagealloc] initWithImage:self.imageView.image];//2. 創(chuàng)建濾鏡self.filter = [CIFilterfilterWithName:filterName keysAndValues:kCIInputImageKey, ciImage,nil];//設(shè)置相關(guān)參數(shù)[self.filter setValue:@(10.f) forKey:@"inputRadius"];//3. 渲染并輸出CIImageCIImage*outputImage = [self.filter outputImage];//4. 獲取繪制上下文self.context = [CIContextcontextWithOptions:nil];//5. 創(chuàng)建輸出CGImageCGImageRefcgImage = [self.context createCGImage:outputImage fromRect:[outputImage extent]];UIImage*image = [UIImageimageWithCGImage:cgImage];//6. 釋放CGImageCGImageRelease(cgImage);returnimage;}
效果如下:
至于濾鏡鏈,則是和普通濾鏡的使用沒什么差別。只要把前一個(gè)濾鏡的輸出,當(dāng)作后一個(gè)濾鏡的輸入,即可實(shí)現(xiàn),就不累述了。
另外,如果想查閱 Filter 的屬性,可以通過attributes屬性來(lái)獲取。比如這個(gè)例子中的CIMotionBlur:
{"CIAttributeFilterAvailable_Mac"="10.4";"CIAttributeFilterAvailable_iOS"="8.3";CIAttributeFilterCategories=? ? (CICategoryBlur,CICategoryStillImage,CICategoryVideo,CICategoryBuiltIn);CIAttributeFilterDisplayName="Motion Blur";CIAttributeFilterName=CIMotionBlur;CIAttributeReferenceDocumentation="http://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CIMotionBlur";inputAngle =? ? {CIAttributeClass=NSNumber;CIAttributeDefault=0;CIAttributeDescription="The angle of the motion determines which direction the blur smears.";CIAttributeDisplayName= Angle;CIAttributeIdentity=0;CIAttributeSliderMax="3.141592653589793";CIAttributeSliderMin="-3.141592653589793";CIAttributeType=CIAttributeTypeAngle;};inputImage =? ? {CIAttributeClass=CIImage;CIAttributeDescription="The image to use as an input image. For filters that also use a background image, this is the foreground image.";CIAttributeDisplayName= Image;CIAttributeType=CIAttributeTypeImage;};inputRadius =? ? {CIAttributeClass=NSNumber;CIAttributeDefault=20;CIAttributeDescription="The radius determines how many pixels are used to create the blur. The larger the radius, the blurrier the result.";CIAttributeDisplayName= Radius;CIAttributeIdentity=0;CIAttributeMin=0;CIAttributeSliderMax=100;CIAttributeSliderMin=0;CIAttributeType=CIAttributeTypeDistance;};}
以上的介紹,可能偏顯蒼白,但是我想說的是,使用內(nèi)置的濾鏡,就是這么簡(jiǎn)單。如果你還想了解更多,可以繼續(xù)閱讀以下這幾篇文章,它們對(duì) Core Image 的基礎(chǔ)概念介紹的更加詳細(xì)。
Core Image 介紹: ObjC 的文章,值得看看。
iOS8 Core Image In Swift:這個(gè)系列是對(duì)官方文檔的一個(gè)完整實(shí)戰(zhàn),講的比較全面。
Core Image Filter Reference:內(nèi)置的所有濾鏡及其用法示例。
Filterpedia:演示了內(nèi)置濾鏡及一些自定義濾鏡的效果,基于 Swift 實(shí)現(xiàn)的。
下面,才是本文著重想要介紹的,算是 Core Image 的一些高級(jí)應(yīng)用。讓我們繼續(xù)往下看~
為了獲取 CIImage,可能有的同學(xué)會(huì)直接通 UIImage.CIImage 的方式去獲取,但是這樣的方式是無(wú)法保證獲取到 CIImage 對(duì)象的。定義如下:
@property(nullable,nonatomic,readonly)CIImage*CIImageNS_AVAILABLE_IOS(5_0);// returns underlying CIImage or nil if CGImageRef based
這里已經(jīng)很明確說明了,UIImage 對(duì)象可能不是基于 CIImage 創(chuàng)建的(比如它是由imageWithCIImage:生成的),這樣就無(wú)法獲取到 CIImage 對(duì)象。
正確的姿勢(shì)應(yīng)該是:
CIImage*ciImage = [[CIImagealloc] initWithImage:self.originalImage];
在創(chuàng)建結(jié)果 UIImage 的時(shí)候,最簡(jiǎn)單的方式就是通過imageWithCIImage來(lái)實(shí)現(xiàn)。這種情況下,不需要顯示的聲明CIContext,因?yàn)?b>imageWithCIImage內(nèi)部自動(dòng)完成了這個(gè)步驟。這使得使用 Core Image 更加的方便。當(dāng)然,它也引起了另外一個(gè)問題,每次都會(huì)重新創(chuàng)建一個(gè)CIContext,然而CIContext的代價(jià)是非常高的。
并且,CIContext 和 CIImage 對(duì)象是不可變的,在線程之間共享這些對(duì)象是安全的。所以多個(gè)線程可以使用同一個(gè) GPU 或者 CPU CIContext 對(duì)象來(lái)渲染 CIImage 對(duì)象。
所以重用 CIContext 是很有必要的。這意味著,我們不應(yīng)該使用imageWithCIImage來(lái)生成 UIImage,而應(yīng)該自己創(chuàng)建維護(hù) CIContext。
比如:
self.context = [CIContextcontextWithOptions:nil];...CGImageRefcgImage = [self.context createCGImage:outputImage fromRect:[outputImage extent]];UIImage*image = [UIImageimageWithCGImage:cgImage];
Core Image 的另外一個(gè)優(yōu)勢(shì),就是可以根據(jù)需求選擇 CPU 或者 GPU 來(lái)處理。
Context 創(chuàng)建的時(shí)候,我們可以給它設(shè)置為是基于 GPU 還是 CPU。
基于 GPU 的話,處理速度更快,因?yàn)槔昧?GPU 硬件的并行優(yōu)勢(shì)。可以使用 OpenGLES 或者 Metal 來(lái)渲染圖像,這種方式CPU完全沒有負(fù)擔(dān),應(yīng)用程序的運(yùn)行循環(huán)不會(huì)受到圖像渲染的影響。
但是 GPU 受限于硬件紋理尺寸,而且如果你的程序在后臺(tái)繼續(xù)處理和保存圖片的話,那么需要使用 CPU,因?yàn)楫?dāng) App 切換到后臺(tái)狀態(tài)時(shí) GPU 處理會(huì)被打斷。使用 CPU 渲染的 iOS 會(huì)采用 GCD 來(lái)對(duì)圖像進(jìn)行渲染,這保證了 CPU 渲染在大部分情況下更可靠,比 GPU 渲染更容易使用,可以在后臺(tái)實(shí)現(xiàn)渲染過程。
綜上,對(duì)于復(fù)雜的圖像濾鏡使用 GPU 更好,但是如果在處理視頻并保存文件,或保存照片到照片庫(kù)中時(shí),為避免程序進(jìn)入后臺(tái)對(duì)圖片保存造成影響,這時(shí)應(yīng)該使用 CPU 進(jìn)行渲染。
用 Apple 官方的一句話來(lái)描述再合適不過了:
CPU is still what will give you the best fidelity where as the GPU will give you the best performance.
具體的設(shè)置方式,可以參考下面的例子:
//創(chuàng)建基于 CPU 的 CIContext 對(duì)象 (默認(rèn)是基于 GPU,CPU 需要額外設(shè)置參數(shù))context = [CIContextcontextWithOptions: [NSDictionarydictionaryWithObject:[NSNumbernumberWithBool:YES] forKey:kCIContextUseSoftwareRenderer]];//創(chuàng)建基于 GPU 的 CIContext 對(duì)象context = [CIContextcontextWithOptions:nil];//創(chuàng)建基于 GPU 的 CIContext 對(duì)象EAGLContext *eaglctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];context = [CIContextcontextWithEAGLContext:eaglctx];
同樣是基于 GPU 的,它們之間也是有區(qū)別的。
contextWithOptions創(chuàng)建的 context 并沒有實(shí)時(shí)性能, 雖然渲染是在 GPU 上執(zhí)行,但是其輸出的 image 是不能顯示的,只有當(dāng)其被復(fù)制回 CPU 存儲(chǔ)器上時(shí),才會(huì)被轉(zhuǎn)成一個(gè)可被顯示的 image 類型,比如 UIImage。
它的渲染過程大致如下:
當(dāng)使用 Core Image 在 GPU 上渲染圖片的時(shí)候,先是把圖像傳遞到 GPU 上,然后執(zhí)行濾鏡相關(guān)操作。但是當(dāng)需要生成 CGImage 對(duì)象的時(shí)候,圖像又被復(fù)制回 CPU 上。最后要在視圖上顯示的時(shí)候,又返回 GPU 進(jìn)行渲染。這樣在 GPU 和 CPU 之前來(lái)回切換,會(huì)造成很嚴(yán)重的性能損耗。
contextWithEAGLContext創(chuàng)建的 context 支持實(shí)時(shí)渲染,渲染圖像的過程始終在 GPU 上進(jìn)行,并且永遠(yuǎn)不會(huì)復(fù)制回 CPU 存儲(chǔ)器上,這就保證了更快的渲染速度和更好的性能。
當(dāng)然,這個(gè)前提是利用實(shí)時(shí)渲染的特效,而不是每次操作都產(chǎn)生一個(gè) UIImage,然后再設(shè)置到視圖上。
比如 OpenGLES:
// 設(shè)置OpenGLES渲染環(huán)境EAGLContext*eaglContext = [[EAGLContextalloc]? initWithAPI:kEAGLRenderingAPIOpenGLES2];self.glkView.context = eaglContext;self.context = [CIContextcontextWithEAGLContext:eaglContext];...// 實(shí)時(shí)渲染[self.pixellateFilter setValue:@(sender.value) forKey:@"inputRadius"];[self.context drawImage:_pixellateFilter.outputImage inRect:_targetBounds? fromRect:_inputImage.extent];[self.glkView.context presentRenderbuffer:GL_RENDERBUFFER];
它的渲染過程大致如下:
并且,iOS8 后增強(qiáng)了 GPU 渲染,在后臺(tái)也能繼續(xù)使用 GPU 進(jìn)行處理。這點(diǎn)會(huì)在下文詳細(xì)說明。
所以應(yīng)該盡可能的使用 GPU 去做圖像處理。
另外,Apple 對(duì) Core Image 內(nèi)部進(jìn)行了優(yōu)化,如果通過
// 創(chuàng)建基于 GPU 的 CIContext 對(duì)象context = [CIContextcontextWithOptions:nil];
創(chuàng)建context,那么它內(nèi)部的渲染器會(huì)根據(jù)設(shè)備最優(yōu)選擇。依次為Metal,OpenGLES,CoreGraphics。
PS:Metal 需要 iOS8 + A7,且模擬器不支持 Metal。OpenGLES3 需要 iOS7 + A7
測(cè)試結(jié)果:
iPhone 6s, iOS 10, 模擬器:OpenGLES3
iPhone 6s,iOS 10,真機(jī):Metal
iPhone 5,iOS 8, 模擬器:OpenGLES
之前提到 CIContext 是線程安全的,然而 CIFilter 并不是線程安全的,這意味著 一個(gè) CIFilter 對(duì)象不能在多個(gè)線程間共享。如果你的操作是多線程的,每個(gè)線程都必須創(chuàng)建自己的 CIFilter 對(duì)象。否則,你的 App 將產(chǎn)生不可預(yù)期的結(jié)果。
其他圖像處理方案的對(duì)比,這里比較有爭(zhēng)議的就是 OpenGLES 和 Core Image 了。
在 OpenGLES 部分,拿主流的GPUImage來(lái)做對(duì)比,分析一下它們各自的優(yōu)缺點(diǎn)。只有對(duì)比了才知道,Core Image 好在哪里,是否值得使用。
PS:以下的優(yōu)勢(shì)闡述,撇去了兩個(gè)框架都具備的,僅保留對(duì)比后各自的優(yōu)勢(shì)。
另外,GPUImage 我沒有深入學(xué)習(xí)過,對(duì)于它的一些優(yōu)勢(shì),主要是總結(jié)它的開發(fā)者 Brad 描述的,以及簡(jiǎn)單的 Demo 進(jìn)行對(duì)比。
GPUImage 優(yōu)勢(shì):
最低支持 iOS 4.0,iOS 5.0 之后就支持自定義濾鏡。
在低端機(jī)型上,GPUImage 有更好的表現(xiàn)。(這個(gè)我沒用真正的設(shè)備對(duì)比過,GPUImage 的主頁(yè)上是這么說的)
GPUImage 在視頻處理上有更好的表現(xiàn)。
GPUImage 的代碼完成公開,實(shí)現(xiàn)透明。
可以根據(jù)自己的業(yè)務(wù)需求,定制更加復(fù)雜的管線操作。可定制程度高。
Core Image 優(yōu)勢(shì):
官方框架,使用放心,維護(hù)方便。
支持 CPU 渲染,可以在后臺(tái)繼續(xù)處理和保存圖片。
一些濾鏡的性能更強(qiáng)勁。例如由 Metal Performance Shaders 支持的模糊濾鏡等。
支持使用 Metal 渲染圖像。而 Metal 在 iOS 平臺(tái)上有更好的表現(xiàn)。
與 Metal,SpriteKit,SceneKit,Core Animation 等更完美的配合。
支持圖像識(shí)別功能。包括人臉識(shí)別、條形碼識(shí)別、文本識(shí)別等。
支持自動(dòng)增強(qiáng)圖像效果,會(huì)分析圖像的直方圖,圖像屬性,臉部區(qū)域,然后通過一組濾鏡來(lái)改善圖像效果。
支持對(duì)原生 RAW 格式圖片的處理。
濾鏡鏈的性能比 GPUImage 高。(沒有驗(yàn)證過,GPUImage 的主頁(yè)上是這么說的)。
支持對(duì)大圖進(jìn)行處理,超過 GPU 紋理限制 (4096 * 4096)的時(shí)候,會(huì)自動(dòng)拆分成幾個(gè)小塊處理(Automatic tiling)。GPUImage 當(dāng)處理超過紋理限制的圖像時(shí)候,會(huì)先做判斷,壓縮成最大紋理限制的圖像,導(dǎo)致圖像質(zhì)量損失。
至此,我覺得 Core Image 的優(yōu)勢(shì)很明顯了,尤其是與 Metal 的配合,自動(dòng)增強(qiáng)圖像效果,支持處理大圖以及濾鏡鏈的優(yōu)化。
下面關(guān)于這幾點(diǎn)優(yōu)化,做個(gè)簡(jiǎn)單的描述。
if you chain together a sequence of filters, Core Image will automatically concatenate these subroutines into a single program.The idea behind this is to improve performance and quality, by reducing the number of intermediate buffers.
Core Image 會(huì)自動(dòng)把多個(gè)濾鏡組合成一個(gè)新的程序(program),通過減少中間緩沖區(qū)的數(shù)量,來(lái)提高性能和質(zhì)量。
超過 GPU 紋理限制 (4096 * 4096)的時(shí)候,會(huì)自動(dòng)拆分成幾個(gè)小塊處理 (Automatic tiling)。
圖片大小:(8374,7780),驗(yàn)證結(jié)果:
PS: rois 表示當(dāng)前處理區(qū)域。 extent 表示圖像實(shí)際大小。
這個(gè)輸出是 Core Image 在處理過程中打印的。
(1) rois=[0020923888] extent=[0083747780](2) rois=[2092020923888] extent=[0083747780](3) rois=[0388820923892] extent=[0083747780](4) rois=[2092388820923892] extent=[0083747780](5) rois=[4184020923888] extent=[0083747780](6) rois=[6276020983888] extent=[0083747780](7) rois=[4184388820923892] extent=[0083747780](8) rois=[6276388820983892] extent=[0083747780]
如果按序講每個(gè)區(qū)域進(jìn)行拼湊,就是原圖的實(shí)際區(qū)域了。
另外,Core Image 對(duì)大圖和小圖的處理上,也有所不同。小圖提前解碼,大圖延遲解碼 !
當(dāng)傳入的 image 是小圖 (size < inputImageMaximumSize)時(shí),在調(diào)用initWithCGImage獲取輸入圖像CIImage的時(shí)候,這個(gè) image 就被完全解碼了。這是很有必要的。因?yàn)樾D可能多次被用到,把編碼的工作提前并且只做一次,一定程度上優(yōu)化性能。
而對(duì)于大圖來(lái)說,它的解碼操作是盡可能延后的(being lazy),直到真正需要顯示, CIContext 執(zhí)行 render 相關(guān)操作。因?yàn)榇髨D的解碼代價(jià)較大,并且不常用,無(wú)腦提前解碼,放到內(nèi)存中是沒有必要的。
下面是驗(yàn)證結(jié)果,選了兩個(gè)相差不大的圖片,但是介于 4096 左右。
4000 * 4000,小圖:
很明顯的,Memory 占有率高,并且調(diào)用了decode相關(guān)操作。
4100 * 4100,大圖:
這里的Memory 占用較低,并且沒有看到decode相關(guān)操作。
同樣的,當(dāng)通過 CIImage 獲取輸出 CGImage 的時(shí)候,如果輸出 CGImage 是小圖的話,那么當(dāng)[CIContext createCGImage]調(diào)用的時(shí)候,image 就被完全渲染了。而對(duì)于大圖,要等到 CGImage 真正需要渲染顯示的時(shí)候,這個(gè) image 才會(huì)被渲染。
/* Render the region 'fromRect' of image 'image' into a temporary buffer using* the context, then create and return a new CoreGraphics image with* the results. The caller is responsible for releasing the returned image.* The return value will be null if size is empty or too big. */#if!defined(SWIFT_CLASS_EXTRA) || (defined(SWIFT_SDK_OVERLAY_COREIMAGE_EPOCH) && SWIFT_SDK_OVERLAY_COREIMAGE_EPOCH >=2)-(nullableCGImageRef)createCGImage:(CIImage*)imagefromRect:(CGRect)fromRect;
經(jīng)過這樣的優(yōu)化處理后,對(duì)于大圖,Session 514給出了直觀的數(shù)據(jù)對(duì)比:
另外一個(gè)很重要的優(yōu)化就是:提高了 iOS 上 Core Image 使用 GPU 進(jìn)行渲染的性能
具體體現(xiàn)在:
1.后臺(tái)操作
短時(shí)間內(nèi),進(jìn)入后臺(tái)后會(huì)依舊使用高效的 GPU 進(jìn)行渲染。
后臺(tái)操作的 GPU 優(yōu)先級(jí)低,不會(huì)對(duì)前臺(tái)的渲染造成性能影響。
2.多線程
iOS 8之前,如果主線程使用 GPU 做相關(guān)操作,次要線程想使用 Core Image 的時(shí)候,通常要使用安全的 CPU 來(lái)實(shí)現(xiàn),避免引起意想不到的問題。
在 iOS 8之后,可以在次要線程設(shè)置 Context 的kCIContextPriorityRequestLow值為 YES,這樣就標(biāo)記為當(dāng)前 Context 在 GPU 上渲染的時(shí)候優(yōu)先級(jí)低,從而不會(huì)影響到 GPU 上高優(yōu)先級(jí)的渲染。
CIContext*context = [CIContextcontextWithOptions: [NSDictionarydictionaryWithObject:[NSNumbernumberWithBool:YES] forKey:kCIContextPriorityRequestLow]];
所以,應(yīng)該盡可能的使用 GPU 進(jìn)行渲染,來(lái)提高性能。
綜上,我認(rèn)為在某需求 Core Image 能實(shí)現(xiàn)的時(shí)候,使用 Core Image 應(yīng)該是 iOS 平臺(tái)上最好的選擇。
至此,我所了解的 Core Image 使用上的注意點(diǎn)已經(jīng)總結(jié)完了,希望你能有所獲~
當(dāng)然,如果你還想了解更多,那么我的下一篇文章:Core Image 自定義 Filter~值得你期待。
Have fun~