着色器图像处理(亮度/对比度/反像)

基于固定基图像的图像混合操作:针对图像各像素与常量值之间的混合操作

图像的基本属性。首先是亮度,也称灰度,它是大 家常说的YUV格式的Y分量,如果使用RGB表示图像,那么可采用前面 章节中提到的公式转换出亮度信息;其次是对比度(contrast),即画面黑与白的比值,也就是从黑到白的渐变层次,比值越大,说明从黑到白的渐变层次越多,色彩表现越丰富;最后是饱和度(saturation),是指 色彩的鲜艳程度,也称为色彩的纯度。

原图

亮度调节

亮度调节有两种一种是线性调节, 一种是非线性调节

亮度值可视为颜色值中“非黑色”的数量。对于RGB颜色值,“浅色” 意味着颜色值分量接近于1.0,而“深色”则意味着颜色值分量接近于0.0。

1.非线性调节

顶点着色器

attribute vec4 position;
attribute vec2 textCoordinate;
varying lowp vec2 varyTextCoord;

void main()
{
    varyTextCoord = textCoordinate;
    gl_Position = position;
}

片元着色器让每一个RGB颜色分量都加上相同的增量

precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;

void main()
{
    /*
     以纹素的方式填充纹理, shader会自动的根据纹理坐标去提取纹素来填充
     colorMap 纹理
     varyTextCoord 纹理坐标
     */
    lowp vec4 temp = texture2D(colorMap, varyTextCoord);
    //取值范围0-1, glsl不允许不同的类进行计算
    float brightness = 0.5;
    gl_FragColor = vec4(temp.r+brightness, temp.g+brightness, temp.b+brightness, temp.a);
}

brightness 可以使用attribute的方式当做参数, 这样可以动态修改

非线性调节结果, 结果感觉像是从外面加了一层蒙版一样的感觉, 不太自然

Simulator Screen Shot - iPhone X - 2019-11-30 at 18.46.14.png
2.线性调节

为什么说线性调节会比较自然呢, 因为人眼并不会去区分RGB颜色分量占多少比例, 而是对明暗比较明暗, HSL就是通过色相(Hue)、饱和度 (Saturation)、明度(Lightness)三个通道的颜色,每个通道都可使用 0~255的数值来表示。这种调节是通过对色相、饱和度、明度三个颜色 通道的变化及其相互之间的叠加来得到各种颜色。符合人眼的直观感觉.

  1. 线性调节的顶点着色器和非线性调节的顶点着色器是一样
precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;

void main()
{
    
    lowp vec4 color = texture2D(colorMap, varyTextCoord);
    
    //这里的HSL是以0-255来表示的, 所以需要先把0-1范围的RGB值转为0-255
    float r = color.r * 255.0;
    float g = color.g * 255.0;
    float b = color.b * 255.0;

    //RGB最大值减去RGB最小值,除以2即为L
    float L = ((max(r, max(g, b)) + min(r, min(g, b))) / 2.0);

    float rHS = 0.0;
    float gHS = 0.0;
    float bHS = 0.0;
    //
    if(L > 128.0) {
        rHS = (r * 128.0 - (L - 128.0) * 256.0) / (256.0 - L);
        gHS = (g * 128.0 - (L - 128.0) * 256.0) / (256.0 - L);
        bHS = (b * 128.0 - (L - 128.0) * 256.0) / (256.0 - L);
    } else {
        rHS = r * 128.0 / L;
        gHS = g * 128.0 / L;
        bHS = b * 128.0 / L;
    }

    // [0-255]
    float delta = 50.0;
    float newL = L + delta - 128.0;
    float newR = .0;
    float newG = .0;
    float newB = .0;
    if(newL > 0.0) {
        newR = rHS + (256.0 - rHS) * newL / 128.0;
        newG = gHS + (256.0 - gHS) * newL / 128.0;
        newB = bHS + (256.0 - bHS) * newL / 128.0;
    } else {
        newR = rHS + rHS * newL / 128.0;
        newG = gHS + gHS * newL / 128.0;
        newB = bHS + bHS * newL / 128.0;
    }
       //这里的值RGB值根据delta值不同, 可能会大于1, 不过在OpenGL ES 中大于1的值会被处理成1, 也就是全部是白色的了.
    gl_FragColor = vec4(newR/255.0, newG/255.0, newB/255.0, color.a);

}
Simulator Screen Shot - iPhone X - 2019-11-30 at 18.46.44.png

看起来好像是比较自然, 从内部向外部出来的颜色.

  1. 前面提到过, 亮度值可视为颜色中非黑色的数量, 所以提升亮度可以通过减少图片展黑色的数量来做.
    使用mix函数来差值减少黑色数量, 如果ratio是0.0,它会返回第一个输入;如果是1.0,会返回第二个输入值。输入0.2则会返回80%的第一个输入颜色和20%的第二个输入颜色,即返回两个纹理的混合色。输入大与1的数, 则会提升图片亮度.
mix(colorA, colorB, ratio)

片元着色器

precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;

void main()
{
    lowp vec4 color = texture2D(colorMap, varyTextCoord);
    lowp vec3 rgb = color.rgb;
    vec3 black = vec3(0.0, 0.0, 0.0);
    float ut = 3.0;
    vec3 mixColor = mix(black, rgb, ut);
    gl_FragColor = vec4(mixColor, color.a);
}

black定义一个黑色, 使用mix来差值计算黑色所占的比例, 下面是当ut值为3时的渲染结果.

Simulator Screen Shot - iPhone X - 2019-12-01 at 13.22.24.png

同样也可以把black改成其他的颜色值, 来混和成不同的结果.

  1. 还有一种更简单的方式直接对RGBA执行一个相同的倍数值

precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;

void main()
{
    vec4 sample0 = texture2D(colorMap, varyTextCoord);
    gl_FragColor = sample0 * 1.5;

}

对比度调节

图像对比度描述了颜色值相对于灰度值的突出程度。当计算图像中的对比度时,可将50%的灰度图作为基图像

vec3(0.5, 0.5, 0.5)

在进行插值计算值, 原图所占的分量越大, 则灰度越少, 对比度越明显, 即ut小于1, 将个颜色分量越接近0.5, 降低图像对比度; 大于1将颜色分量远离0.5, 增加对比度;

precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;

void main()
{
    lowp vec4 color = texture2D(colorMap, varyTextCoord);
    lowp vec3 rgb = color.rgb;
    //亮度
//    vec3 target = vec3(0.0, 0.0, 0.0);
    //对比度
    vec3 target = vec3(0.5, 0.5, 0.5);
    float ut = 2.5;
    vec3 mixColor = mix(target, rgb, ut);
    gl_FragColor = vec4(mixColor, color.a);

}
Simulator Screen Shot - iPhone X - 2019-12-01 at 14.22.08.png

反像

反像操作针对图像的“负”数据的工作方式进行建模,从白色中减去各像素的颜色值即可获得反像,如下所示:

vec3(1.0,1.0, 1.0) - color.rgb 

基于负像的片元着色器代码,分别创建了某一颜色值及其负值。随后,可用变量uT对其进行混合。uT= 1处表示原始颜色值,uT= 0处则表示负值。

precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;

void main()
{
    lowp vec4 color = texture2D(colorMap, varyTextCoord);
    lowp vec3 rgb = color.rgb;
    //亮度
//    vec3 target = vec3(0.0, 0.0, 0.0);
    //对比度
//    vec3 target = vec3(0.5, 0.5, 0.5);
    //反像
    vec3 neg = vec3(1.0, 1.0, 1.0) - rgb;
    float ut = 0.0;
    gl_FragColor = vec4(mix(neg, rgb, ut), color.a);

}
Simulator Screen Shot - iPhone X - 2019-12-01 at 14.39.11.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,928评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,748评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,282评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,065评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,101评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,855评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,521评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,414评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,931评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,053评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,191评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,873评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,529评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,074评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,188评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,491评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,173评论 2 357

推荐阅读更多精彩内容