處理圖像
處理圖像意味著應(yīng)用濾鏡 - 圖像濾鏡是逐像素檢查輸入圖像,在算法上應(yīng)用某種效果以創(chuàng)建輸出圖像败明。 在Core Image中隘马,圖像處理依賴于CIFilter和CIImage類,它們描述了濾鏡及其輸入和輸出妻顶。 要應(yīng)用濾鏡并顯示或?qū)С鼋Y(jié)果酸员,可以使用Core Image和其他系統(tǒng)框架之間的集成,或使用CIContext類創(chuàng)建您自己的渲染工作流程讳嘱。 本章介紹使用這些類來應(yīng)用濾鏡和渲染結(jié)果的關(guān)鍵概念幔嗦。
CoreImage擁有三個類來支持圖像處理:
CIFilter,是個可變對象沥潭,它代表了一種效果邀泉。一個濾鏡對象至少有一個輸入?yún)?shù)并且產(chǎn)生一個輸出圖像。
CIImage钝鸽,是一個不可變對象汇恤,它表示一個圖像。一個CIImage所需的圖像數(shù)據(jù)拔恰,你可以直接合成因谎,或者從一個文件中提供出來,也可以從一個CIFilter對象的輸出來獲取颜懊。
CIContext财岔,是Core Image繪制濾鏡產(chǎn)生的結(jié)果的地方。Core Image上下文可以基于CPU或者GPU河爹。
概覽
在您的應(yīng)用程序中使用Core Image進(jìn)行圖像處理有很多方法匠璧。基本示例
// 創(chuàng)建一個CIContext對象
CIContext *context = [CIContext contextWithOptions:nil];
// 創(chuàng)建一個CIImage對象咸这。你可以通過各種資源創(chuàng)建CIImage
CIImage *image = [CIImage imageWithContentsOfURL:myURL];
// 創(chuàng)建一個濾鏡夷恍,然后設(shè)置它的輸入?yún)?shù)
CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone"];
[filter setValue:image forKey:kCIInputImageKey];
[filter setValue:@0.8f forKey:kCIInputIntensityKey];
// 獲取輸出圖像,該圖像只是如何產(chǎn)生圖像的一種方式媳维,它還沒有被渲染
CIImage *result = [filter valueForKey:kCIOutputImageKey];
CGRect extent = [result extent];
// 將CIImage渲染成CoreGraphics圖像用來顯示或者保存為文件
CGImageRef cgImage = [context createCGImage:result fromRect:extent];
圖像是濾鏡的輸入和輸出
Core Image濾鏡處理和生成Core Image圖像裁厅。 CIImage實(shí)例是表示圖像的不可變對象冰沙。這些對象不直接表示圖像位圖數(shù)據(jù) - 相反,CIImage對象是用于生成圖像的“方法”执虹。一個方法可能需要從文件加載圖像;另一個可能代表濾鏡或?yàn)V鏡鏈的輸出拓挥。Core Image只有在您要求呈現(xiàn)圖像以供顯示或輸出時才執(zhí)行這些ff。
要應(yīng)用濾鏡袋励,請創(chuàng)建一個或多個表示要由濾鏡處理的圖像的CIImage對象侥啤,并將它們分配給濾鏡的輸入?yún)?shù)(例如kCIInputImageKey)。你幾乎可以從任何圖像數(shù)據(jù)源創(chuàng)建一個Core Image圖像對象茬故,其中包括:
- 引用要加載的圖像文件的URL或包含圖像文件數(shù)據(jù)的NSData對象
Quartz2D盖灸,UIKit或AppKit圖像表示(CGImageRef,UIImage或NSBitmapImageRep對象) - Metal磺芭,OpenGL或OpenGL ES紋理
- CoreVideo圖像或像素緩沖區(qū)(CVImageBufferRef或CVPixelBufferRef)
- 在進(jìn)程之間共享圖像數(shù)據(jù)的IOSurfaceRef對象
- 內(nèi)存中的圖像位圖數(shù)據(jù)(指向此類數(shù)據(jù)的指針或按需提供數(shù)據(jù)的CIImageProvider對象)
有關(guān)創(chuàng)建CIImage對象的完整列表赁炎,請參閱CIImage類參考。
由于CIImage對象描述如何生成圖像(而不是包含圖像數(shù)據(jù))钾腺,因此它也可以表示濾鏡輸出徙垫。當(dāng)你訪問CIFilter對象的outputImage屬性時,Core Image僅會識別并存儲執(zhí)行濾鏡所需的步驟放棒。這些步驟僅在你請求將圖像渲染以供顯示或輸出時執(zhí)行姻报。你可以使用CIContextrender或繪圖方法之一(請參閱使用Core Image上下文構(gòu)建自己的工作流程)或通過使用與Core Image一起工作的許多系統(tǒng)框架之一顯示圖像來顯式請求渲染(請參閱集成與其他框架)。
延遲處理直至渲染時間使Core Image快速高效间螟。在渲染時吴旋,Core Image可以查看是否需要將多個濾鏡應(yīng)用于圖像。如果是這樣厢破,它會自動連接多個“配方”并組織它們以消除冗余操作荣瑟,因此每個像素只處理一次而不是多次。
濾鏡描述圖像處理效果
CIFilter類的一個實(shí)例是一個表示圖像處理效果的可變對象以及控制該效果行為的任何參數(shù)摩泪。要使用濾鏡褂傀,您可以創(chuàng)建CIFilter對象,設(shè)置其輸入?yún)?shù)加勤,然后訪問其輸出圖像(請參閱圖像是以下濾鏡的輸入和輸出)。調(diào)用filterWithName:initializer以使用系統(tǒng)已知的濾鏡名稱實(shí)例化濾鏡對象(請參閱查詢?yōu)V鏡或Core Image濾鏡參考的系統(tǒng))同波。
大多數(shù)濾鏡都有一個或多個輸入?yún)?shù)鳄梅,可讓你控制處理的完成方式。每個輸入?yún)?shù)都有一個指定其數(shù)據(jù)類型的屬性類未檩,如NSNumber戴尸。輸入?yún)?shù)可以有其他屬性,例如默認(rèn)值冤狡,允許的最小值和最大值孙蒙,參數(shù)的顯示名稱以及CIFilter類參考中描述的其他屬性项棠。例如,CIColorMonochrome濾鏡具有三個輸入?yún)?shù) - 要處理的圖像挎峦,單色和顏色強(qiáng)度香追。
濾鏡參數(shù)被定義為鍵值對;要使用參數(shù),通常使用valueForKey:和setValue:forKey:方法或基于鍵值編碼(例如Core Animation)的其他功能坦胶。key是標(biāo)識屬性的常數(shù)透典,value是與key關(guān)聯(lián)的設(shè)置。Core Image屬性值通常使用屬性值數(shù)據(jù)類型中列出的數(shù)據(jù)類型之一顿苇。
重要提示:CIFilter對象是可變的峭咒,因此你不能在不同線程之間安全地共享它們。 每個線程都必須創(chuàng)建自己的
CIFilter對象纪岁。 但是凑队,濾鏡的輸入和輸出CIImage對象是不可變的,因此可以安全地在線程之間傳遞幔翰。
復(fù)雜效果的濾鏡鏈
每個Core Image濾鏡都會生成一個輸出CIImage對象漩氨,因此您可以將此對象用作另一個濾鏡的輸入。 例如导匣,圖中所示的濾鏡序列將顏色效果應(yīng)用于圖像才菠,然后添加發(fā)光效果,最后從結(jié)果中裁剪出一部分贡定。
圖中通過連接濾鏡輸入和輸出來構(gòu)建濾鏡鏈
Core Image優(yōu)化了濾鏡鏈的應(yīng)用赋访,例如這種濾鏡鏈以快速高效地渲染結(jié)果。 鏈中的每個CIImage對象都不是完全渲染的圖像缓待,而僅僅是渲染的“方式”蚓耽。Core Image不需要單獨(dú)執(zhí)行每個濾鏡,浪費(fèi)時間和內(nèi)存渲染永遠(yuǎn)不會看到的中間像素緩沖區(qū)旋炒。 相反步悠,Core Image將濾鏡組合成單個操作,甚至可以在以不同順序應(yīng)用濾鏡時重新組織濾鏡瘫镇,從而更有效地生成相同的結(jié)果鼎兽。 圖1-2更精確的展示了圖1-1中示例的濾鏡鏈。
圖1-2 Core Image將濾鏡鏈優(yōu)化為單個操作
請注意铣除,在圖1-2中谚咬,裁剪操作已從上一次移至第一次。 該濾鏡會導(dǎo)致原始圖像的大部分區(qū)域被裁剪成最終輸出尚粘。 因此择卦,不需要應(yīng)用顏色并銳化這些像素的濾鏡。 通過執(zhí)行裁剪,Core Image確保了高成本的只有像素級的圖像處理操作在最終輸出中可見秉继。
下面示例如何設(shè)置如上所示的濾鏡鏈祈噪。
func applyFilterChain(to image: CIImage) -> CIImage {
// The CIPhotoEffectInstant filter takes only an input image
let colorFilter = CIFilter(name: "CIPhotoEffectProcess", withInputParameters:
[kCIInputImageKey: image])!
// Pass the result of the color filter into the Bloom filter
// and set its parameters for a glowy effect.
let bloomImage = colorFilter.outputImage!.applyingFilter("CIBloom",
withInputParameters: [
kCIInputRadiusKey: 10.0,
kCIInputIntensityKey: 1.0
])
// imageByCroppingToRect is a convenience method for
// creating the CICrop filter and accessing its outputImage.
let cropRect = CGRect(x: 350, y: 350, width: 150, height: 150)
let croppedImage = bloomImage.cropping(to: cropRect)
return croppedImage
}
以上代碼還展示了一些用于配置濾鏡和訪問其結(jié)果的不同方法∩屑總之辑鲤,你可以使用這些方法中的任何一種來單獨(dú)或作為濾鏡鏈的一部分應(yīng)用濾鏡:
- 使用filterWithName:initializer創(chuàng)建CIFilter實(shí)例,使用setValue:forKey:方法(包括要處理的圖像的kCIInputImageKey)設(shè)置參數(shù)腌巾,并使用outputImage屬性訪問輸出圖像遂填。
- 使用filterWithName:withInputParameters:initializer創(chuàng)建一個CIFilter實(shí)例并將其參數(shù)(包括輸入圖像)設(shè)置為一次調(diào)用,然后使用outputImage屬性訪問輸出澈蝙。
- 通過將imageByApplyingFilter:withInputParameters:方法應(yīng)用于CIImage對象吓坚,應(yīng)用濾鏡而不創(chuàng)建CIFilter實(shí)例。
- 對于某些常用的濾鏡操作(如剪切灯荧,夾緊和應(yīng)用坐標(biāo)變換)礁击,請使用通過修改現(xiàn)有圖像創(chuàng)建圖像中列出的其他CIImage實(shí)例方法。
使用特殊濾鏡類型獲取更多選項
大多數(shù)內(nèi)置的Core Image濾鏡都在主輸入圖像上運(yùn)行(可能會附加影響處理的輸入圖像)并創(chuàng)建單個輸出圖像逗载。但還有其他幾種類型可用于創(chuàng)建有趣的效果哆窿,或與其他濾鏡結(jié)合使用以生成更復(fù)雜的工作流程。
-
合成(或混合)濾鏡根據(jù)預(yù)設(shè)公式組合兩個圖像厉斟。例如:
CISourceInCompositing濾鏡組合圖像挚躯,使得只有輸入圖像中不透明的區(qū)域在輸出圖像中可見。 CIMultiplyBlendMode濾鏡將兩個圖像的像素顏色相乘擦秽,產(chǎn)生一個變暗的輸出圖像码荔。 有關(guān)合成濾鏡的完整列表,請查詢CICategoryCompositeOperation類別感挥。
注意:您可以在合成之前安排輸入圖像缩搅,方法是對每個圖像應(yīng)用幾何調(diào)整。請參閱CICategoryGeometryAdjustment篩選器類別或imageByApplyingTransform:方法触幼。
-
generator 濾鏡不輸入圖像硼瓣。相反,這些濾鏡使用其他輸入?yún)?shù)從頭開始創(chuàng)建新圖像置谦。一些發(fā)生器產(chǎn)生的輸出可以獨(dú)立使用堂鲤,其他發(fā)生器可以組合成濾波器鏈以產(chǎn)生更有趣的圖像。內(nèi)置Core Image濾鏡中的一些示例包括:
像CIQRCodeGenerator和CICode128BarcodeGenerator這樣的濾鏡會生成對指定的輸入數(shù)據(jù)進(jìn)行編碼的條形碼圖像媒峡。 像CIConstantColorGenerator瘟栖,CICheckerboardGenerator和CILinearGradient這樣的濾鏡可以從指定的顏色生成簡單的過程圖像。 您可以將這些濾鏡與其他濾鏡結(jié)合使用以獲得有趣的效果 - 例如丝蹭,CIRadialGradient濾鏡可以創(chuàng)建用于CIMaskedVariableBlur濾鏡的遮罩。 像CILenticularHaloGenerator和CISunbeamsGenerator這樣的濾鏡可以創(chuàng)建獨(dú)立的視覺效果 - 將這些與合成濾鏡結(jié)合使用,為圖像添加特殊效果奔穿。
要查找生成器濾鏡镜沽,請查詢CICategoryGenerator和CICategoryGradient類別。
-
縮減濾鏡對輸入圖像進(jìn)行操作贱田,但不是以傳統(tǒng)意義創(chuàng)建輸出圖像缅茉,而是其輸出描述關(guān)于輸入圖像的信息。例如:
CIAreaMaximum濾鏡輸出表示圖像指定區(qū)域中所有像素顏色中最亮的單個顏色值男摧。 CIAreaHistogram濾鏡輸出有關(guān)圖像指定區(qū)域中每個強(qiáng)度值的像素數(shù)量的信息蔬墩。
所有Core Image濾鏡都必須生成一個CIImage對象作為它們的輸出,所以由還原濾鏡生成的信息仍然是一個圖像耗拓。但是拇颅,通常不顯示這些圖像 - 相反,您可以從單像素或單行圖像讀取顏色值乔询,或?qū)⑺鼈冇米髌渌麨V鏡的輸入樟插。
有關(guān)減少濾鏡的完整列表,請查詢CICategoryReduction類別竿刁。
-
一個轉(zhuǎn)換濾鏡接受兩個輸入圖像黄锤,并根據(jù)一個獨(dú)立變量改變它們之間的輸出 - 通常,這個變量是時間食拜,因此您可以使用轉(zhuǎn)換濾鏡創(chuàng)建一個動畫鸵熟,以一個圖像開始,結(jié)束于另一個圖像负甸,并前進(jìn)從一個到另一個使用有趣的視覺效果流强。Core Image提供了幾個內(nèi)置的過渡濾鏡,包括:
CIDissolveTransition濾鏡產(chǎn)生一個簡單的交叉消解惑惶,從一個圖像到另一個圖像漸變煮盼。 CICopyMachineTransition濾鏡模擬復(fù)印機(jī),在一幅圖像上劃過一道明亮的光線以顯示另一幅圖像带污。
有關(guān)轉(zhuǎn)換濾鏡的完整列表僵控,請查詢CICategoryTransition類別。