Core Image框架詳細(xì)解析(九) —— 子類化CIFilter:自定義效果的配方 Subclassing CIFilter: Recipes for Custom Effects(一)

版本記錄

版本號 時間
V1.0 2018.01.28

前言

Core Image是IOS5中新加入的一個框架外恕,里面提供了強(qiáng)大高效的圖像處理功能,用來對基于像素的圖像進(jìn)行操作與分析乡翅。還提供了很多強(qiáng)大的濾鏡,可以實現(xiàn)你想要的效果惧磺,下面我們就一起解析一下這個框架渣淤。感興趣的可以參考上面幾篇赏寇。
1. Core Image框架詳細(xì)解析(一) —— 基本概覽
2. Core Image框架詳細(xì)解析(二) —— Core Image濾波器參考
3. Core Image框架詳細(xì)解析(三) —— 關(guān)于Core Image
4. Core Image框架詳細(xì)解析(四) —— Processing Images處理圖像(一)
5. Core Image框架詳細(xì)解析(五) —— Processing Images處理圖像(二)
6. Core Image框架詳細(xì)解析(六) —— 圖像中的面部識別Detecting Faces in an Image(一)
7. Core Image框架詳細(xì)解析(七) —— 自動增強(qiáng)圖像 Auto Enhancing Images
8. Core Image框架詳細(xì)解析(八) —— 查詢系統(tǒng)中的過濾器 Querying the System for Filters

子類化CIFilter:自定義效果的配方

您可以使用一個圖像濾鏡的輸出作為另一個圖像濾鏡的輸入來創(chuàng)建自定義效果,并根據(jù)需要鏈接盡可能多的濾鏡价认。 當(dāng)您通過多次使用這種方式創(chuàng)建效果時嗅定,請考慮繼承CIFilter并封裝過濾器的效果。

本章介紹Core Image如何繼承自CIFilter類并創(chuàng)建為CIColorInvert濾鏡用踩。 然后它描述了鏈接在一起的各種過濾器的recipes渠退,以實現(xiàn)有趣的效果。 按照Subclassing CIFilter to Create the CIColorInvert Filter的子類化過程捶箱,您應(yīng)該能夠從本章中的配方創(chuàng)建過濾器智什,或者創(chuàng)建自己感興趣的Core Image提供的內(nèi)置過濾器組合。


Subclassing CIFilter to Create the CIColorInvert Filter - 子類CIFilter創(chuàng)建CIColorInvert過濾器

當(dāng)您對CIFilter進(jìn)行子類化時丁屎,您可以通過使用預(yù)設(shè)值對其進(jìn)行編碼或?qū)⑺鼈冩溄釉谝黄饋硇薷默F(xiàn)有的過濾器荠锭。 Core Image使用這種技術(shù)實現(xiàn)了一些內(nèi)置的過濾器。

要創(chuàng)建一個過濾器的子類晨川,您需要執(zhí)行以下任務(wù):

  • 聲明過濾器輸入?yún)?shù)的屬性证九。 您必須在每個輸入?yún)?shù)名稱前添加input删豺,如inputImage。

  • 如有必要愧怜,重寫setDefaults方法呀页。 (這個例子中沒有必要,因為輸入?yún)?shù)是設(shè)定值拥坛。)

  • 重寫outputImage方法蓬蝶。

Core Image提供的CIColorInvert濾鏡是CIColorMatrix濾鏡的變體。 顧名思義猜惋,CIColorInvert將矢量提供給CIColorMatrix丸氛,以反轉(zhuǎn)輸入圖像的顏色。 按照Listing 5-1和Listing 5-2所示的簡單示例構(gòu)建自己的過濾器著摔。

// Listing 5-1  The interface for the CIColorInvert filter

@interface CIColorInvert: CIFilter {
    CIImage *inputImage;
}
@property (retain, nonatomic) CIImage *inputImage;
@end
// Listing 5-2  The outputImage method for the CIColorInvert filter

@implementation CIColorInvert
@synthesize inputImage;
- (CIImage *) outputImage
{
      CIFilter *filter = [CIFilter filterWithName:@"CIColorMatrix"
                            withInputParameters: @{
            kCIInputImageKey: inputImage,
        @"inputRVector": [CIVector vectorWithX:-1 Y:0 Z:0],
        @"inputGVector": [CIVector vectorWithX:0 Y:-1 Z:0],
        @"inputBVector": [CIVector vectorWithX:0 Y:0 Z:-1],
        @"inputBiasVector": [CIVector vectorWithX:1 Y:1 Z:1],
      return filter.outputImage;
}

Chroma Key Filter Recipe - 色度鍵過濾配方

從源圖像中移除顏色或顏色范圍缓窜,然后將源圖像與背景圖像進(jìn)行合成。

Figure 5-1 The Chroma Key filter processing chain

創(chuàng)建色度鍵過濾器:

  • 創(chuàng)建映射您想要移除的顏色值的數(shù)據(jù)的立方體貼圖谍咆,使其透明(alpha值為0.0)禾锤。
  • 使用CIColorCube過濾器和立方體貼圖從源圖像中刪除色度鍵顏色。
  • 使用CISourceOverCompositing過濾器將處理后的源圖像混合到背景圖像上

以下部分顯示如何執(zhí)行每個步驟摹察。

1. Create a Cube Map - 創(chuàng)建一個多維數(shù)據(jù)圖

彩色立方體是3D顏色查找表恩掷。Core Image過濾器CIColorCube將顏色值作為輸入,并將查找表應(yīng)用于這些值港粱。 CIColorCube的默認(rèn)查找表是一個單位矩陣螃成,意思是它對提供的數(shù)據(jù)沒有任何作用旦签。但是查坪,這個recipe要求你從圖像中刪除所有的綠色。 (如果您愿意宁炫,可以移除不同的顏色偿曙。)

你需要通過設(shè)置綠色到alpha = 0.0來清除圖像中的所有綠色,這使得透明羔巢。 “Green”包含一系列的顏色望忆。最直接的方法是將圖像中的顏色值從RGBA轉(zhuǎn)換為HSV值。在HSV中竿秆,hue色調(diào)表示為圍繞圓柱的中心軸的角度启摄。在該表示中,可以將顏色可視化為餅圖切片幽钢,然后簡單地刪除表示色度鍵顏色的切片歉备。

要去除綠色,您需要定義包含綠色色調(diào)的中央通道周圍的最小和最大角度匪燕。那么蕾羊,對于任何綠色的東西喧笔,您將其alpha值設(shè)置為0.0。純綠色的數(shù)值相當(dāng)于120o龟再。最小和最大角度需要以該值為中心书闸。

立方體貼圖數(shù)據(jù)必須預(yù)乘alpha,所以創(chuàng)建立方體貼圖的最后一步是將RGB值乘以剛剛計算的alpha值利凑,對于綠色的色調(diào)為0.0浆劲,否則為1.0。Listing 5-3顯示了如何創(chuàng)建此過濾器recipe所需的顏色立方體哀澈。

// Listing 5-3  The color cube in code

// Allocate memory
const unsigned int size = 64;
float *cubeData = (float *)malloc (size * size * size * sizeof (float) * 4);
float rgb[3], hsv[3], *c = cubeData;

// Populate cube with a simple gradient going from 0 to 1
for (int z = 0; z < size; z++){
    rgb[2] = ((double)z)/(size-1); // Blue value
    for (int y = 0; y < size; y++){
        rgb[1] = ((double)y)/(size-1); // Green value
        for (int x = 0; x < size; x ++){
            rgb[0] = ((double)x)/(size-1); // Red value
            // Convert RGB to HSV
            // You can find publicly available rgbToHSV functions on the Internet
            rgbToHSV(rgb, hsv);
            // Use the hue value to determine which to make transparent
            // The minimum and maximum hue angle depends on
            // the color you want to remove
            float alpha = (hsv[0] > minHueAngle && hsv[0] < maxHueAngle) ? 0.0f: 1.0f;
            // Calculate premultiplied alpha values for the cube
            c[0] = rgb[0] * alpha;
            c[1] = rgb[1] * alpha;
            c[2] = rgb[2] * alpha;
            c[3] = alpha;
            c += 4; // advance our pointer into memory for the next color value
        }
    }
}

// Create memory with the cube data
NSData *data = [NSData dataWithBytesNoCopy:cubeData
                       length:cubeDataSize
                       freeWhenDone:YES];
CIColorCube *colorCube = [CIFilter filterWithName:@"CIColorCube"];
[colorCube setValue:@(size) forKey:@"inputCubeDimension"];

// Set data for cube
[colorCube setValue:data forKey:@"inputCubeData"];

2. Remove green from the source image -

從源圖像中刪除綠色

現(xiàn)在梳侨,您已經(jīng)有了彩色map數(shù)據(jù),將前景圖像(即日丹,要從中去除綠色的圖像)提供給CIColorCube濾鏡并獲取輸出圖像

[colorCube setValue:myInputImage forKey:kCIInputImageKey];
CIImage *result = [colorCube valueForKey:kCIOutputImageKey];

3. Blend the processed source image over a background image - 將處理的源圖像混合到背景圖像上

設(shè)置CISourceOverCompositing過濾器的輸入?yún)?shù)如下:

  • inputImage設(shè)置為從CIColorCube過濾器生成的圖像走哺。
  • inputBackgroundImage設(shè)置為顯示新背景的圖像。 這個例子使用海灘圖像哲虾。

現(xiàn)在丙躏,前景圖像就好像在沙灘上一樣。


White Vignette for Faces Filter Recipe - 面孔過濾Recipe的白色小插圖

增加圖像中檢測到的臉部周圍圖像的亮度束凑。

Figure 5-2 The White Vignette filter processing chain

要創(chuàng)建一個白色的小插圖過濾器:

  • 在圖像中找到人臉晒旅。
    使用以臉部為中心的CIRadialGradient創(chuàng)建基本陰影貼圖。
  • 將基本陰影貼圖與原始圖像混合汪诉。

以下部分顯示如何執(zhí)行每個步驟废恋。

1. Find the Face - 找到臉部

使用CIDetector類在圖像中定位面部。 featuresInImage:options:返回數(shù)組中的第一個元素扒寄,就是濾波器要作用的面部鱼鼓。 在識別臉部后,從探測器提供的邊界計算臉部的中心该编。 您需要中心值來創(chuàng)建陰影圖迄本。 Listing 5-4顯示了如何使用CIDetector定位面部。

// Listing 5-4  Using CIDetector to locate one face

CIDetector *detector = [CIDector detectorOfType:CIDetectorTypeFace
                                        context:nil
                                        options:nil];
NSArray *faceArray = [detector featuresInImage:image options:nil];
CIFeature *face = faceArray[0];
CGFloat xCenter = face.bounds.origin.x + face.bounds.size.width/2.0;
CGFloat yCenter = face.bounds.origin.y + face.bounds.size.height/2.0;
CIVector *center = [CIVector vectorWithX:xCenter Y:yCenter];

2. Create a Shade Map - 創(chuàng)建一個陰影圖

使用CIRadialGradient過濾器創(chuàng)建一個居中于人臉的陰影貼圖课竣。 陰影貼圖的中心應(yīng)該是透明的嘉赎,以便圖像中的面部保持不變。 圖的邊緣應(yīng)該是不透明的白色于樟。 兩者之間的區(qū)域應(yīng)該有不同程度的透明度公条。

要達(dá)到此效果,請將輸入?yún)?shù)設(shè)置為CIRadialGradient迂曲,如下所示:

  • inputRadius0設(shè)置為大于圖像最長尺寸的值靶橱。
  • inputRadius1設(shè)置為比face更大的值,例如face.bounds.size.height + 50
  • inputColor0設(shè)置為不透明的白色抓韩。
  • inputColor1設(shè)置為透明白色纠永。
  • inputCenter設(shè)置為您使用Listing 5-4計算的面部邊界的中心。

3. Blend the Gradient with the Face - 與臉部融合的漸變

設(shè)置CISourceOverCompositing過濾器的輸入?yún)?shù)如下:

  • inputImage設(shè)置為原始圖像谒拴。
  • inputBackgroundImage設(shè)置為上一步生成的陰影貼圖尝江。

Tilt-Shift Filter Recipe - 傾斜移位濾波器Recipe

選擇性地聚焦圖像以模擬微型場景。

Figure 5-3 The Tilt-Shift filter processing chain

要創(chuàng)建一個傾斜移位濾鏡:

  • 創(chuàng)建圖像的模糊版本英上。
  • 創(chuàng)建兩個線性漸變炭序。
  • 通過合成線性漸變創(chuàng)建一個蒙版。
  • 合成模糊的圖像苍日,蒙版和原始圖像惭聂。

以下部分顯示如何執(zhí)行每個步驟。

1. Create a Blurred Version of the image - 創(chuàng)建圖像的模糊版本

設(shè)置CIGaussianBlur過濾器的輸入?yún)?shù)如下:

  • inputImage設(shè)置為要處理的圖像相恃。
  • inputRadius設(shè)置為10.0(這是默認(rèn)值)辜纲。

2. Create Two Linear Gradients - 創(chuàng)建兩個線性漸變

使用從上到下變化的單一顏色(例如綠色或灰色)創(chuàng)建線性漸變。 設(shè)置CILinearGradient的輸入?yún)?shù)如下:

  • inputPoint0設(shè)置為(0拦耐,0.75 * h)
  • inputColor0設(shè)置為(0,1,0,1)
  • inputPoint1設(shè)置為(0耕腾,0.5 * h)
  • inputColor1設(shè)置為(0,1,0,0)

創(chuàng)建一個從下到上變化的綠色線性漸變。 設(shè)置CILinearGradient的輸入?yún)?shù)如下:

  • inputPoint0設(shè)置為(0,0.25 * h)
  • inputColor0設(shè)置為(0,1,0,1)
  • inputPoint1設(shè)置為(0杀糯,0.5 * h)
  • inputColor1設(shè)置為(0,1,0,0)

3. Create a Mask from the Linear Gradients - 從線性漸變創(chuàng)建一個蒙版

要創(chuàng)建一個遮罩扫俺,請按如下方式設(shè)置CIAdditionCompositing濾鏡的輸入?yún)?shù):

  • inputImage設(shè)置為您創(chuàng)建的第一個線性漸變。
  • inputBackgroundImage設(shè)置為您創(chuàng)建的第二個線性漸變固翰。

4. Combine the Blurred Image, Source Image, and the Gradients - 結(jié)合模糊圖像狼纬,源圖像和漸變

最后一步是使用CIBlendWithMask過濾器,設(shè)置輸入?yún)?shù)如下:

  • inputImage設(shè)置為圖像的模糊版本骂际。
  • inputBackgroundImage設(shè)置為原始未處理的圖像疗琉。
  • inputMaskImage設(shè)置為蒙版,即組合的漸變方援。

蒙版只會影響圖像的外部没炒。 蒙版的透明部分將通過原始未處理的圖像顯示涛癌。 蒙版的不透明部分允許顯示模糊的圖像犯戏。

后記

本篇已結(jié)束,后面更精彩~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拳话,一起剝皮案震驚了整個濱河市先匪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弃衍,老刑警劉巖呀非,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡岸裙,警方通過查閱死者的電腦和手機(jī)猖败,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來降允,“玉大人恩闻,你說我怎么就攤上這事【缍” “怎么了幢尚?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長翅楼。 經(jīng)常有香客問我尉剩,道長,這世上最難降的妖魔是什么毅臊? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任理茎,我火速辦了婚禮,結(jié)果婚禮上管嬉,老公的妹妹穿的比我還像新娘功蜓。我一直安慰自己,他們只是感情好宠蚂,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布式撼。 她就那樣靜靜地躺著,像睡著了一般求厕。 火紅的嫁衣襯著肌膚如雪著隆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天呀癣,我揣著相機(jī)與錄音美浦,去河邊找鬼。 笑死项栏,一個胖子當(dāng)著我的面吹牛浦辨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播沼沈,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼流酬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了列另?” 一聲冷哼從身側(cè)響起芽腾,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎页衙,沒想到半個月后摊滔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阴绢,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年艰躺,在試婚紗的時候發(fā)現(xiàn)自己被綠了呻袭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡腺兴,死狀恐怖棒妨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情含长,我是刑警寧澤券腔,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站拘泞,受9級特大地震影響纷纫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜陪腌,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一辱魁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧诗鸭,春花似錦染簇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蝌箍,卻和暖如春青灼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背妓盲。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工杂拨, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人悯衬。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓弹沽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親筋粗。 傳聞我的和親對象是個殘疾皇子策橘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

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