我們可以刪除一幅圖像中指定的顏色膛腐,然后填充一個背景。類似好萊塢大片的背景合成。
要實(shí)現(xiàn)上面圖片的效果有下面幾個步驟
- 首先我們要從圖像中刪除我們要刪掉的顏色或听,通過創(chuàng)建一個顏色矩陣,將要刪除的顏色變換成透明色笋婿。
- 用CICOlorCube 濾鏡刪除圖像中通過矩陣變換過的顏色誉裆。
- 最后用 CISourceOverCompositing 合成圖片。
創(chuàng)建一個 color Cube Map
一個color cube是一個3D顏色查找表(lookup table)缸濒。Core Image 濾鏡 CIColorCube 使用色值作為輸入足丢,并應(yīng)用一個查找表到這些色值。CIColorCube
從圖像中刪除所有的綠色庇配。就是要把圖中的把綠色的alpha
值設(shè)置為0.0(透明)斩跌。
“綠色”包括一定范圍內(nèi)的顏色。最直接的處理方式是把圖像的色值從RGBA轉(zhuǎn)為HSV讨永。HSV把顏色描述在圓柱坐標(biāo)系內(nèi)的點(diǎn)滔驶。
要刪除綠色,你需要定義圍繞中心點(diǎn)的最小和最大的角度卿闹。之后,對于任何的綠色萝快,將其alpha值設(shè)置為0.0锻霎。純綠的相對角度是120o。最小值和最大值要以這個值為中心揪漩。
我們要消除的“深綠色”并不只是視覺上的一種顏色旋恼,而是顏色的范圍,最直接的方法是將RGBA轉(zhuǎn)成HSV(Hue奄容,Saturation冰更,Value),在HSV的格式下昂勒,顏色是圍繞圓柱體中軸的角度來表現(xiàn)的蜀细,在這種表現(xiàn)方法下,你能把顏色的范圍想象成連在一起的扇形戈盈,然后直接把該塊區(qū)域干掉(alpha設(shè)為0)奠衔,這就表示我們實(shí)際上需要指定顏色區(qū)域的范圍------圍繞圓柱體中軸線的最小角度以及最大角度,此范圍內(nèi)的顏色alpha設(shè)為0塘娶。最后归斤,Cube Map表中的數(shù)據(jù)必須乘以alpha,所以創(chuàng)建Cube Map的最后一步是把RGB值乘以你剛剛計(jì)算出來的alpha值:如果是想要消除的顏色刁岸,乘出來就是0脏里,反之則不變
可以看到如果是純綠色,其取值是120度虹曙,藍(lán)色是240度迫横,在這個網(wǎng)站上可以看到更詳細(xì)的RGB顏色對應(yīng)的HSV值鸦难。
Cube map數(shù)據(jù)必須預(yù)乘alpha,所以創(chuàng)建cube map的最后一步是把RGB值乘以你剛剛計(jì)算出的alpha值(如果是綠色员淫,就是0合蔽,如果不是就是1.0) 下面是例子代碼。
struct CubeMap createCubeMap(float minHueAngle, float maxHueAngle) {
const unsigned int size = 64;
struct CubeMap map;
map.length = size * size * size * sizeof (float) * 4;
map.dimension = size;
float *cubeData = (float *)malloc (map.length);
float rgb[3], hsv[3], *c = cubeData;
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
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
}
}
}
map.data = cubeData;
return map;
}
我們一般得到的UIColor時一個RGB顏色介返,需要轉(zhuǎn)為HSV拴事,Apple提供了getHue方法,這樣我們就能通過var hsvCol = RGBtoHSV(R, g: G, b: B)
獲得HSV圣蝎,在通過hsvCol.h獲取得到Hue并乘以360度獲取改顏色所在的度數(shù)刃宵。
func RGBtoHSV(r : CGFloat, g : CGFloat, b : CGFloat) -> (h : CGFloat, s : CGFloat, v : CGFloat) {
var h : CGFloat = 0.0
var s : CGFloat = 0.0
var v : CGFloat = 0.0
let col = UIColor(red: r, green: g, blue: b, alpha: 1.0)
col.getHue(&h, saturation: &s, brightness: &v, alpha: nil)
return (h, s, v)
}