Core Image專題(二)

處理圖像

處理圖像意味著應(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)建濾鏡鏈

1-1.png

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.png

請注意铣除,在圖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類別。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鱼冀,一起剝皮案震驚了整個濱河市报破,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌千绪,老刑警劉巖充易,帶你破解...
    沈念sama閱讀 212,222評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異荸型,居然都是意外死亡盹靴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稿静,“玉大人梭冠,你說我怎么就攤上這事「谋福” “怎么了控漠?”我有些...
    開封第一講書人閱讀 157,720評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長悬钳。 經(jīng)常有香客問我盐捷,道長,這世上最難降的妖魔是什么默勾? 我笑而不...
    開封第一講書人閱讀 56,568評論 1 284
  • 正文 為了忘掉前任碉渡,我火速辦了婚禮,結(jié)果婚禮上灾测,老公的妹妹穿的比我還像新娘爆价。我一直安慰自己,他們只是感情好媳搪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,696評論 6 386
  • 文/花漫 我一把揭開白布铭段。 她就那樣靜靜地躺著,像睡著了一般秦爆。 火紅的嫁衣襯著肌膚如雪序愚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,879評論 1 290
  • 那天等限,我揣著相機(jī)與錄音爸吮,去河邊找鬼。 笑死望门,一個胖子當(dāng)著我的面吹牛形娇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播筹误,決...
    沈念sama閱讀 39,028評論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼桐早,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了厨剪?” 一聲冷哼從身側(cè)響起哄酝,我...
    開封第一講書人閱讀 37,773評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎祷膳,沒想到半個月后陶衅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,220評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡直晨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,550評論 2 327
  • 正文 我和宋清朗相戀三年搀军,在試婚紗的時候發(fā)現(xiàn)自己被綠了膨俐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,697評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡罩句,死狀恐怖吟策,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情的止,我是刑警寧澤,帶...
    沈念sama閱讀 34,360評論 4 332
  • 正文 年R本政府宣布着撩,位于F島的核電站诅福,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏拖叙。R本人自食惡果不足惜氓润,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,002評論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望薯鳍。 院中可真熱鬧咖气,春花似錦、人聲如沸挖滤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斩松。三九已至伶唯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惧盹,已是汗流浹背乳幸。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钧椰,地道東北人粹断。 一個月前我還...
    沈念sama閱讀 46,433評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像嫡霞,于是被迫代替她去往敵國和親瓶埋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,587評論 2 350

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