android 用opengles实现几个简单的ps叠加方法和简单的滤镜再转成bitmap

最近修改滤镜,发现这篇文章终于把photoshop图层叠加模式讲清楚了 ,就想着实现这篇文章的效果,就做了个小demo

2019/09/04更新

增加了把各种滤镜转bitmap的方法

至于效果对不对我也不知道,因为我没装ps就算装了我也不会用

那篇文章的最后两个没有实现,收缩和补偿值不知道是啥,也就跳过了

关于A和B,我理解为A是背景图片,B是叠加图片,所以shader代码内A是color1,B是color2,如果我的理解和文章刚好相反的话直接对调一下就可以了

接下来贴shader代码,至于文件名,我实在不知道这么多方法英文叫啥,而且我也懒得查就直接用拼音了

变暗  color_bian_an_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = min(color1,color2);
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

变亮  color_bian_liang_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = max(color1,color2);
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

正片叠底  color_zheng_pian_die_di_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = color1*color2;
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

滤色  color_lv_se_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = 1.0 - (1.0 - color1)*(1.0 - color2);
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

颜色加深  color_yan_se_jia_shen_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = color1 - (1.0 - color1)*(1.0 - color2)/color2;
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

颜色减淡  color_yan_se_jian_dan_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = color1 + color1*color2/(1.0 - color2);
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

线性加深  color_xian_xing_jia_shen_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = color1 + color2 - 1.0;
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

线性减淡  color_xian_xing_jian_dan_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = color1 + color2;
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

叠加  color_die_jia_fs.glsl

uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba;
        if(color1.r > 0.5)
            rgba.r = 1.0 - 2.0 * (1.0 - color1.r) * (1.0 - color2.r);
        else
            rgba.r = 2.0 * color1.r * color2.r;
        if(color1.g > 0.5)
            rgba.g = 1.0 - 2.0 * (1.0 - color1.g) * (1.0 - color2.g);
        else
            rgba.g = 2.0 * color1.g * color2.g;
        if(color1.b > 0.5)
            rgba.b = 1.0 - 2.0 * (1.0 - color1.b) * (1.0 - color2.b);
        else
            rgba.b = 2.0 * color1.b * color2.b;
        rgba.a = 1.0;
        gl_FragColor = rgba;
    }
}

强光  color_qiang_guang_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba;
        if(color2.r > 0.5)
            rgba.r = 1.0 - 2.0 * (1.0 - color1.r) * (1.0 - color2.r);
        else
            rgba.r = 2.0 * color1.r * color2.r;
        if(color2.g > 0.5)
            rgba.g = 1.0 - 2.0 * (1.0 - color1.g) * (1.0 - color2.g);
        else
            rgba.g = 2.0 * color1.g * color2.g;
        if(color2.b > 0.5)
            rgba.b = 1.0 - 2.0 * (1.0 - color1.b) * (1.0 - color2.b);
        else
            rgba.b = 2.0 * color1.b * color2.b;
        rgba.a = 1.0;
        gl_FragColor = rgba;
    }
}

柔光  color_rou_guang_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba;
        if(color2.r > 0.5)
            rgba.r = color1.r*(1.0 - color2.r)+sqrt(color1.r)*(2.0*color2.r - 1.0);
        else
            rgba.r = 2.0 * color1.r * color2.r + color1.r * color1.r *(1.0 - 2.0*color2.r);
        if(color2.g > 0.5)
            rgba.g = color1.g*(1.0 - color2.g)+sqrt(color1.g)*(2.0*color2.g - 1.0);
        else
            rgba.g = 2.0 * color1.g * color2.g + color1.g * color1.g *(1.0 - 2.0*color2.g);
        if(color2.b > 0.5)
            rgba.b = color1.b*(1.0 - color2.b)+sqrt(color1.b)*(2.0*color2.b - 1.0);
        else
            rgba.b = 2.0 * color1.b * color2.b + color1.b * color1.b *(1.0 - 2.0*color2.b);
        rgba.a = 1.0;
        gl_FragColor = rgba;
    }
}

亮光  color_liang_guang_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba;
        if(color2.r > 0.5)
            rgba.r = color1.r + color1.r*(2.0*color2.r - 1.0)/(2.0*(1.0 - color2.r));
        else
            rgba.r = color1.r - (1.0 - color1.r)*(1.0 - 2.0*color2.r)/(2.0*color2.r);
        if(color2.g > 0.5)
            rgba.g = color1.g + color1.g*(2.0*color2.g - 1.0)/(2.0*(1.0 - color2.g));
        else
            rgba.g = color1.g - (1.0 - color1.g)*(1.0 - 2.0*color2.g)/(2.0*color2.g);
        if(color2.b > 0.5)
            rgba.b = color1.b + color1.b*(2.0*color2.b - 1.0)/(2.0*(1.0 - color2.b));
        else
            rgba.b = color1.b - (1.0 - color1.b)*(1.0 - 2.0*color2.b)/(2.0*color2.b);
        rgba.a = 1.0;
        gl_FragColor = rgba;
    }
}

点光  color_dian_guang_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba;
        if(color2.r > 0.5)
            rgba.r = min(color1.r,2.0 * color2.r - 1.0);
        else
            rgba.r = min(color1.r,2.0 * color2.r);
        if(color2.g > 0.5)
            rgba.g = min(color1.g,2.0 * color2.g - 1.0);
        else
            rgba.g = min(color1.g,2.0 * color2.g);
        if(color2.b > 0.5)
            rgba.b = min(color1.b,2.0 * color2.b - 1.0);
        else
            rgba.b = min(color1.b,2.0 * color2.b);
        rgba.a = 1.0;
        gl_FragColor = rgba;
    }
}

线性光  color_xian_xing_guang_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = color1 + 2.0 * color2 - 1.0;
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

实色混合  color_shi_se_hun_he_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba;
        if(color1.r + color2.r >= 1.0)
            rgba.r = 1.0;
        else
            rgba.r = 0.0;
        if(color1.g + color2.g >= 1.0)
            rgba.g = 1.0;
        else
            rgba.g = 0.0;
        if(color1.b + color2.b >= 1.0)
            rgba.b = 1.0;
        else
            rgba.b = 0.0;
        rgba.a = 1.0;
        gl_FragColor = rgba;
    }
}

排除  color_pai_chu_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = color1 + color2 - 2.0 * color1 * color2;
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

差值  color_cha_zhi_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    if(color2.a == 0.0){
        gl_FragColor = color1;
    }else if(color2.a != 1.0){
        gl_FragColor = mix(color1,color2,color2.a);
    }else{
        highp vec4 rgba = abs(color1 - color2);
        gl_FragColor = vec4(rgba.rgb,1.0);
    }
}

2019/8/30更新

又找到一篇文章图像处理的滤镜算法,也试着做了一下

在测试去色滤镜的时候发现显示效果和灰度滤镜差不多,看代码和他的图片感觉不对,当rgb三个值是一样的时候,这一像素就是灰色的,而示例图片明显发绿,然后我百度了一下发现去色就是指将彩色图像通过运算转化成灰度图像,所以代码应该是对的,可能图片用错了,当然这只是我的理解,仅供参考

里头的高斯模糊在我的这篇文章Android opengles 动态调节高斯模糊内实现了,我就没加上

贴shader代码,文件名当然还是拼音

灰度  color_hui_du_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp float grey = (color1.r+color1.g+color1.b)/3.0;
    gl_FragColor = vec4(grey,grey,grey,1.0);
}

黑白  color_hei_bai_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp float grey = (color1.r+color1.g+color1.b)/3.0;
    if(grey >= 100.0/255.0){
        grey = 1.0;
    }else{
        grey = 0.0;
    }
    gl_FragColor = vec4(grey,grey,grey,1.0);
}

反向  color_fan_xiang_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    gl_FragColor = vec4(1.0 - color1.r,1.0 - color1.g,1.0 - color1.b,1.0);
}

去色 color_qu_se_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp float min_color = min(min(color1.r,color1.g),color1.b);
    highp float max_color = max(max(color1.r,color1.g),color1.b);
    highp float floor_color =(min_color + max_color)*0.5;
    gl_FragColor = vec4(floor_color,floor_color,floor_color,1.0);
}

单色  color_dan_se_fs.glsl文章里是红色,我测试改成绿色了

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    gl_FragColor = vec4(0.0,color1.g,0.0,1.0);
}

怀旧  color_huai_jiu_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp float r = 0.393 * color1.r + 0.769 * color1.g + 0.189 * color1.b;
    highp float g = 0.349 * color1.r + 0.686 * color1.g + 0.168 * color1.b;
    highp float b = 0.272 * color1.r + 0.534 * color1.g + 0.131 * color1.b;
    r = r < 0.0 ? 0.0 : r > 1.0 ? 1.0 : r;
    g = g < 0.0 ? 0.0 : g > 1.0 ? 1.0 : g;
    b = b < 0.0 ? 0.0 : b > 1.0 ? 1.0 : b;
    gl_FragColor = vec4(r,g,b,1.0);
}

熔铸  color_rong_zhu_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp float r = color1.r * 0.5 / (color1.g + color1.b);
    highp float g = color1.g * 0.5 / (color1.r + color1.b);
    highp float b = color1.b * 0.5 / (color1.r + color1.g);
    r = r < 0.0 ? 0.0 : r > 1.0 ? 1.0 : r;
    g = g < 0.0 ? 0.0 : g > 1.0 ? 1.0 : g;
    b = b < 0.0 ? 0.0 : b > 1.0 ? 1.0 : b;
    gl_FragColor = vec4(r,g,b,1.0);
}

冰冻  color_bing_dong_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp float r = (color1.r - color1.g - color1.b)*3.0*0.5;
    highp float g = (color1.g - color1.r - color1.b)*3.0*0.5;
    highp float b = (color1.b - color1.g - color1.r)*3.0*0.5;
    r = r < 0.0 ? 0.0 : r > 1.0 ? 1.0 : r;
    g = g < 0.0 ? 0.0 : g > 1.0 ? 1.0 : g;
    b = b < 0.0 ? 0.0 : b > 1.0 ? 1.0 : b;
    gl_FragColor = vec4(r,g,b,1.0);
}

连环画  color_lian_huan_hua_fs.glsl

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp float r = abs(color1.g - color1.b + color1.g + color1.r) * color1.r;
    highp float g = abs(color1.b - color1.g + color1.b + color1.r) * color1.r;
    highp float b = abs(color1.b - color1.g + color1.b + color1.r) * color1.g;
    gl_FragColor = vec4(r,g,b,1.0);
}

褐色  color_he_se_fs.glsl代码和怀旧一样的

varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
    highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
    highp float r = 0.393 * color1.r + 0.769 * color1.g + 0.189 * color1.b;
    highp float g = 0.349 * color1.r + 0.686 * color1.g + 0.168 * color1.b;
    highp float b = 0.272 * color1.r + 0.534 * color1.g + 0.131 * color1.b;
    gl_FragColor = vec4(r,g,b,1.0);
}

 

Github

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章