GPUImageGrayscaleFilter
灰度滤镜。获取图片的灰度图方法有很多种,常见的有平均值法
、心理学法
、去饱和法
、分解法
、单一通道法
等。
- 平均值法
G r e y = ( R e d + G r e e n + B l u e ) / 3 Grey = (Red + Green + Blue) / 3 Grey=(Red+Green+Blue)/3 - 心理学法
G r e y = ( R e d ∗ 0.3 + G r e e n ∗ 0.59 + B l u e ∗ 0.11 ) Grey = (Red * 0.3 + Green * 0.59 + Blue * 0.11) Grey=(Red∗0.3+Green∗0.59+Blue∗0.11)
类似的还有:
G r e y = ( R e d ∗ 0.2126 + G r e e n ∗ 0.7152 + B l u e ∗ 0.0722 ) Grey = (Red * 0.2126 + Green * 0.7152 + Blue * 0.0722) Grey=(Red∗0.2126+Green∗0.7152+Blue∗0.0722)
G r e y = ( R e d ∗ 0.299 + G r e e n ∗ 0.587 + B l u e ∗ 0.114 ) Grey = (Red * 0.299 + Green * 0.587 + Blue * 0.114) Grey=(Red∗0.299+Green∗0.587+Blue∗0.114) - 去饱和法
G r e y = ( m a x ( R e d , G r e e n , B l u e ) + m i n ( R e d , G r e e n , B l u e ) ) / 2 Grey = (max(Red, Green, Blue) + min(Red, Green, Blue) ) / 2 Grey=(max(Red,Green,Blue)+min(Red,Green,Blue))/2 - 分解法
G r e y = m a x ( R e d , G r e e n , B l u e ) 或 G r e y = m i n ( R e d , G r e e n , B l u e ) Grey = max(Red, Green, Blue) 或 Grey = min(Red, Green, Blue) Grey=max(Red,Green,Blue)或Grey=min(Red,Green,Blue) - 单一通道法
G r e y = R e d Grey = Red Grey=Red 或 G r e y = G r e e n Grey = Green Grey=Green或 G r e y = B l u e Grey = Blue Grey=Blue
参考来源:图片灰度转换算法
GPUImage采用的是心理学法。
vec2 uv = fragCoord/iResolution.xy;
const vec3 W = vec3(0.2125, 0.7154, 0.0721);
vec4 col = texture(iChannel0,uv);
// to grey
float grey = dot(col.rgb,W);
fragColor = vec4(vec3(grey),1.0);
注解:dot(col.rgb,W) = col.r * W.x + col.g * W.y + col.b * W.z


GPUImageFalseColorFilter
替换滤镜,将原来图片的色彩替换为指定的色彩。
const vec3 W = vec3(0.2125, 0.7154, 0.0721);
vec2 uv = fragCoord/iResolution.xy;
vec4 col = texture(iChannel0,uv);
// 将原来的图像转为灰度图
float grey = dot(col.rgb,W);
vec3 firstCol = vec3(0.,0.,.5);
vec3 secondCol = vec3(1.,0.,0.);
// 混合两种颜色到灰度图中
col.rgb = mix(firstCol,secondCol,grey);
fragColor = vec4(col.rgb,1.0);
mix函数
:
m
i
x
(
x
,
y
,
a
)
=
(
1.0
−
a
)
∗
x
+
y
∗
a
mix(x,y,a) = (1.0 - a) * x + y * a
mix(x,y,a)=(1.0−a)∗x+y∗a



GPUImageSepiaFilter
深黑色滤镜。深黑色颜色转换公式如下:
R
e
d
=
0.393
∗
R
e
d
+
0.769
∗
G
r
e
e
n
+
0.189
∗
B
l
u
e
;
G
r
e
e
n
=
0.349
∗
R
e
d
+
0.686
∗
G
r
e
e
n
+
0.168
∗
B
l
u
e
;
B
l
u
e
=
0.272
∗
R
e
d
+
0.534
∗
G
r
e
e
n
+
0.131
∗
B
l
u
e
;
Red = 0.393 * Red + 0.769 * Green + 0.189 * Blue;\\ Green = 0.349 * Red + 0.686 * Green + 0.168 * Blue;\\ Blue = 0.272 * Red + 0.534 * Green + 0.131 * Blue;
Red=0.393∗Red+0.769∗Green+0.189∗Blue;Green=0.349∗Red+0.686∗Green+0.168∗Blue;Blue=0.272∗Red+0.534∗Green+0.131∗Blue;
vec2 uv = fragCoord/iResolution.xy;
vec4 col = texture(iChannel0,uv);
// common
const mat3 RGBToSepiaMatrix = mat3(
0.393,0.769,0.189,
0.349,0.686,0.168,
0.272,0.534,0.131
);
const float sepiaIntensity = 1.;//强度
col.rgb = mix(col.rgb,col.rgb * RGBToSepiaMatrix,sepiaIntensity);
fragColor = vec4(col.rgb,1.0);


而GPUImageSepiaFilter
采用的颜色转换矩阵是:
// from GPUImage's GPUImageSepiaFilter
const mat3 RGBToSepiaMatrixOther = mat3(
0.3588,0.7044,0.1368,
0.2990,0.5870,0.1140,
0.2392,0.4696,0.0912
);
这个矩阵我在网上找了很久也没找到具体出处,不过使用该颜色转换矩阵后渲染出的图像褐色效果要比上图深。如果有谁知道具体出处请告诉我一声。


GPUImageCGAColorspaceFilter
CGA滤镜。CGA全称是:Color Graphics Adapter,彩色图形适配器(关于CGA的更多资料请访问Color Graphics Adapter)。在320x200标准图形模式下,可以选择3种固定的调色板:
1.CGA 320×200 in 4 colors palette 0 (red, yellow, green, black background)
2.CGA 320×200 in 4 colors palette 1 (cyan, magenta, white, black background)
3.CGA 320×200 in 4 colors 3rd palette (tweaked), (cyan, red, white, black background)
GPUImageCGAColorspaceFilter
使用的是第二种调色板。
vec2 uv = fragCoord/iResolution.xy;
// 采样大小
vec2 sampleDivisor = vec2(1./200.,1./320.);
// 获取采样后的坐标
vec2 samplePos = uv - mod(uv,sampleDivisor);
vec4 col = texture(iChannel0,samplePos);
// 4种颜色
vec4 whiteCol = vec4(1.);
vec4 blackCol = vec4(0.,0.,0.,1.);
vec4 cyanCol = vec4(0.33,1.,1.,1.);
vec4 magentaCol = vec4(1.,0.33,1.,1.);
// 和当前位置的颜色进行比较 获取一个比较标准
float whiteDis = length(col-whiteCol);
float blackDis = length(col-blackCol);
float cyanDis = length(col-cyanCol);
float magentaDis = length(col-magentaCol);
// 获取和当前位置的颜色最接近的色彩
float finalDis = min(min(min(whiteDis,blackDis),cyanDis),magentaDis);
vec4 finalCol = vec4(0.);
if (finalDis == whiteDis){
finalCol = whiteCol;
}else if (finalDis == blackDis) {
finalCol = blackCol;
}else if (finalDis == cyanDis) {
finalCol = cyanCol;
}else{
finalCol = magentaCol;
}
// 渲染到屏幕上
fragColor = finalCol;


