色彩调整之灰度、替换、深褐色、CGA滤镜

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=(Red0.3+Green0.59+Blue0.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=(Red0.2126+Green0.7152+Blue0.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=(Red0.299+Green0.587+Blue0.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.0a)x+ya

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.393Red+0.769Green+0.189Blue;Green=0.349Red+0.686Green+0.168Blue;Blue=0.272Red+0.534Green+0.131Blue;

 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;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值