版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.01.28 |
前言
Core Image是IOS5中新加入的一個(gè)框架,里面提供了強(qiáng)大高效的圖像處理功能,用來對(duì)基于像素的圖像進(jìn)行操作與分析。還提供了很多強(qiáng)大的濾鏡,可以實(shí)現(xiàn)你想要的效果,下面我們就一起解析一下這個(gè)框架。感興趣的可以參考上面幾篇。
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ì)解析(六) —— 圖像中的面部識(shí)別Detecting Faces in an Image(一)
7. Core Image框架詳細(xì)解析(七) —— 自動(dòng)增強(qiáng)圖像 Auto Enhancing Images
8. Core Image框架詳細(xì)解析(八) —— 查詢系統(tǒng)中的過濾器 Querying the System for Filters
子類化CIFilter:自定義效果的配方
您可以使用一個(gè)圖像濾鏡的輸出作為另一個(gè)圖像濾鏡的輸入來創(chuàng)建自定義效果,并根據(jù)需要鏈接盡可能多的濾鏡。 當(dāng)您通過多次使用這種方式創(chuàng)建效果時(shí),請(qǐng)考慮繼承CIFilter并封裝過濾器的效果。
本章介紹Core Image如何繼承自CIFilter類并創(chuàng)建為CIColorInvert
濾鏡。 然后它描述了鏈接在一起的各種過濾器的recipes
,以實(shí)現(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)您對(duì)CIFilter
進(jìn)行子類化時(shí),您可以通過使用預(yù)設(shè)值對(duì)其進(jìn)行編碼或?qū)⑺鼈冩溄釉谝黄饋硇薷默F(xiàn)有的過濾器。 Core Image使用這種技術(shù)實(shí)現(xiàn)了一些內(nèi)置的過濾器。
要?jiǎng)?chuàng)建一個(gè)過濾器的子類,您需要執(zhí)行以下任務(wù):
聲明過濾器輸入?yún)?shù)的屬性。 您必須在每個(gè)輸入?yún)?shù)名稱前添加
input
,如inputImage。如有必要,重寫
setDefaults
方法。 (這個(gè)例子中沒有必要,因?yàn)檩斎雲(yún)?shù)是設(shè)定值。)重寫
outputImage
方法。
Core Image提供的CIColorInvert
濾鏡是CIColorMatrix
濾鏡的變體。 顧名思義,CIColorInvert
將矢量提供給CIColorMatrix
,以反轉(zhuǎn)輸入圖像的顏色。 按照Listing 5-1和Listing 5-2所示的簡(jiǎn)單示例構(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)行合成。
創(chuàng)建色度鍵過濾器:
- 創(chuàng)建映射您想要移除的顏色值的數(shù)據(jù)的立方體貼圖,使其透明(alpha值為0.0)。
- 使用
CIColorCube
過濾器和立方體貼圖從源圖像中刪除色度鍵顏色。 - 使用
CISourceOverCompositing
過濾器將處理后的源圖像混合到背景圖像上
以下部分顯示如何執(zhí)行每個(gè)步驟。
1. Create a Cube Map - 創(chuàng)建一個(gè)多維數(shù)據(jù)圖
彩色立方體是3D顏色查找表。Core Image過濾器CIColorCube
將顏色值作為輸入,并將查找表應(yīng)用于這些值。 CIColorCube
的默認(rèn)查找表是一個(gè)單位矩陣,意思是它對(duì)提供的數(shù)據(jù)沒有任何作用。但是,這個(gè)recipe
要求你從圖像中刪除所有的綠色。 (如果您愿意,可以移除不同的顏色。)
你需要通過設(shè)置綠色到alpha = 0.0來清除圖像中的所有綠色,這使得透明。 “Green”包含一系列的顏色。最直接的方法是將圖像中的顏色值從RGBA轉(zhuǎn)換為HSV值。在HSV中,hue色調(diào)表示為圍繞圓柱的中心軸的角度。在該表示中,可以將顏色可視化為餅圖切片,然后簡(jiǎn)單地刪除表示色度鍵顏色的切片。
要去除綠色,您需要定義包含綠色色調(diào)的中央通道周圍的最小和最大角度。那么,對(duì)于任何綠色的東西,您將其alpha值設(shè)置為0.0。純綠色的數(shù)值相當(dāng)于120o。最小和最大角度需要以該值為中心。
立方體貼圖數(shù)據(jù)必須預(yù)乘alpha,所以創(chuàng)建立方體貼圖的最后一步是將RGB值乘以剛剛計(jì)算的alpha值,對(duì)于綠色的色調(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è)置為顯示新背景的圖像。 這個(gè)例子使用海灘圖像。
現(xiàn)在,前景圖像就好像在沙灘上一樣。
White Vignette for Faces Filter Recipe - 面孔過濾Recipe的白色小插圖
增加圖像中檢測(cè)到的臉部周圍圖像的亮度。
要?jiǎng)?chuàng)建一個(gè)白色的小插圖過濾器:
- 在圖像中找到人臉。
使用以臉部為中心的CIRadialGradient
創(chuàng)建基本陰影貼圖。 - 將基本陰影貼圖與原始圖像混合。
以下部分顯示如何執(zhí)行每個(gè)步驟。
1. Find the Face - 找到臉部
使用CIDetector
類在圖像中定位面部。 featuresInImage:options:
返回?cái)?shù)組中的第一個(gè)元素,就是濾波器要作用的面部。 在識(shí)別臉部后,從探測(cè)器提供的邊界計(jì)算臉部的中心。 您需要中心值來創(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)建一個(gè)陰影圖
使用CIRadialGradient
過濾器創(chuàng)建一個(gè)居中于人臉的陰影貼圖。 陰影貼圖的中心應(yīng)該是透明的,以便圖像中的面部保持不變。 圖的邊緣應(yīng)該是不透明的白色。 兩者之間的區(qū)域應(yīng)該有不同程度的透明度。
要達(dá)到此效果,請(qǐng)將輸入?yún)?shù)設(shè)置為CIRadialGradient
,如下所示:
- 將
inputRadius0
設(shè)置為大于圖像最長(zhǎng)尺寸的值。 - 將
inputRadius1
設(shè)置為比face更大的值,例如face.bounds.size.height + 50
。 - 將
inputColor0
設(shè)置為不透明的白色。 - 將
inputColor1
設(shè)置為透明白色。 - 將
inputCenter
設(shè)置為您使用Listing 5-4計(jì)算的面部邊界的中心。
3. Blend the Gradient with the Face - 與臉部融合的漸變
設(shè)置CISourceOverCompositing
過濾器的輸入?yún)?shù)如下:
- 將
inputImage
設(shè)置為原始圖像。 - 將
inputBackgroundImage
設(shè)置為上一步生成的陰影貼圖。
Tilt-Shift Filter Recipe - 傾斜移位濾波器Recipe
選擇性地聚焦圖像以模擬微型場(chǎng)景。
要?jiǎng)?chuàng)建一個(gè)傾斜移位濾鏡:
- 創(chuàng)建圖像的模糊版本。
- 創(chuàng)建兩個(gè)線性漸變。
- 通過合成線性漸變創(chuàng)建一個(gè)蒙版。
- 合成模糊的圖像,蒙版和原始圖像。
以下部分顯示如何執(zhí)行每個(gè)步驟。
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)建兩個(gè)線性漸變
使用從上到下變化的單一顏色(例如綠色或灰色)創(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)建一個(gè)從下到上變化的綠色線性漸變。 設(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)建一個(gè)蒙版
要?jiǎng)?chuàng)建一個(gè)遮罩,請(qǐng)按如下方式設(shè)置CIAdditionCompositing
濾鏡的輸入?yún)?shù):
- 將
inputImage
設(shè)置為您創(chuàng)建的第一個(gè)線性漸變。 - 將
inputBackgroundImage
設(shè)置為您創(chuàng)建的第二個(gè)線性漸變。
4. Combine the Blurred Image, Source Image, and the Gradients - 結(jié)合模糊圖像,源圖像和漸變
最后一步是使用CIBlendWithMask
過濾器,設(shè)置輸入?yún)?shù)如下:
- 將
inputImage
設(shè)置為圖像的模糊版本。 - 將
inputBackgroundImage
設(shè)置為原始未處理的圖像。 - 將
inputMaskImage
設(shè)置為蒙版,即組合的漸變。
蒙版只會(huì)影響圖像的外部。 蒙版的透明部分將通過原始未處理的圖像顯示。 蒙版的不透明部分允許顯示模糊的圖像。
后記
本篇已結(jié)束,后面更精彩~~~