Core Image基礎(chǔ)

前言

最近在研究 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 概述

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ù)往下看~

注意點(diǎn)

1. image.CIImage == nil

為了獲取 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];

2. CIContext

在創(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];

3. CPU / GPU

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

4. CIFilter

之前提到 CIContext 是線程安全的,然而 CIFilter 并不是線程安全的,這意味著 一個(gè) CIFilter 對(duì)象不能在多個(gè)線程間共享。如果你的操作是多線程的,每個(gè)線程都必須創(chuàng)建自己的 CIFilter 對(duì)象。否則,你的 App 將產(chǎn)生不可預(yù)期的結(jié)果。

Core Image vs GPUImage

其他圖像處理方案的對(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)單的描述。

1. 濾鏡鏈

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ì)量。

2. 支持大圖

超過 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ì)比:

3. GPU 優(yōu)化

另外一個(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~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,778評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,218評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,436評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,795評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,993評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,229評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,687評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,990評(píng)論 2 374

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