基于固定基圖像的圖像混合操作:針對圖像各像素與常量值之間的混合操作
圖像的基本屬性。首先是亮度,也稱灰度,它是大 家常說的YUV格式的Y分量,如果使用RGB表示圖像,那么可采用前面 章節(jié)中提到的公式轉(zhuǎn)換出亮度信息;其次是對比度(contrast),即畫面黑與白的比值,也就是從黑到白的漸變層次,比值越大,說明從黑到白的漸變層次越多,色彩表現(xiàn)越豐富;最后是飽和度(saturation),是指 色彩的鮮艷程度,也稱為色彩的純度。

亮度調(diào)節(jié)
亮度調(diào)節(jié)有兩種一種是線性調(diào)節(jié), 一種是非線性調(diào)節(jié)
亮度值可視為顏色值中“非黑色”的數(shù)量。對于RGB顏色值,“淺色” 意味著顏色值分量接近于1.0,而“深色”則意味著顏色值分量接近于0.0。
1.非線性調(diào)節(jié)
頂點(diǎn)著色器
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會自動的根據(jù)紋理坐標(biāo)去提取紋素來填充
colorMap 紋理
varyTextCoord 紋理坐標(biāo)
*/
lowp vec4 temp = texture2D(colorMap, varyTextCoord);
//取值范圍0-1, glsl不允許不同的類進(jìn)行計算
float brightness = 0.5;
gl_FragColor = vec4(temp.r+brightness, temp.g+brightness, temp.b+brightness, temp.a);
}
brightness 可以使用attribute的方式當(dāng)做參數(shù), 這樣可以動態(tài)修改
非線性調(diào)節(jié)結(jié)果, 結(jié)果感覺像是從外面加了一層蒙版一樣的感覺, 不太自然

2.線性調(diào)節(jié)
為什么說線性調(diào)節(jié)會比較自然呢, 因為人眼并不會去區(qū)分RGB顏色分量占多少比例, 而是對明暗比較明暗, HSL就是通過色相(Hue)、飽和度 (Saturation)、明度(Lightness)三個通道的顏色,每個通道都可使用 0~255的數(shù)值來表示。這種調(diào)節(jié)是通過對色相、飽和度、明度三個顏色 通道的變化及其相互之間的疊加來得到各種顏色。符合人眼的直觀感覺.
- 線性調(diào)節(jié)的頂點(diǎn)著色器和非線性調(diào)節(jié)的頂點(diǎn)著色器是一樣
precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main()
{
lowp vec4 color = texture2D(colorMap, varyTextCoord);
//這里的HSL是以0-255來表示的, 所以需要先把0-1范圍的RGB值轉(zhuǎn)為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值根據(jù)delta值不同, 可能會大于1, 不過在OpenGL ES 中大于1的值會被處理成1, 也就是全部是白色的了.
gl_FragColor = vec4(newR/255.0, newG/255.0, newB/255.0, color.a);
}

看起來好像是比較自然, 從內(nèi)部向外部出來的顏色.
- 前面提到過, 亮度值可視為顏色中非黑色的數(shù)量, 所以提升亮度可以通過減少圖片展黑色的數(shù)量來做.
使用mix函數(shù)來差值減少黑色數(shù)量, 如果ratio是0.0,它會返回第一個輸入;如果是1.0,會返回第二個輸入值。輸入0.2則會返回80%的第一個輸入顏色和20%的第二個輸入顏色,即返回兩個紋理的混合色。輸入大與1的數(shù), 則會提升圖片亮度.
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來差值計算黑色所占的比例, 下面是當(dāng)ut值為3時的渲染結(jié)果.

同樣也可以把
black改成其他的顏色值, 來混和成不同的結(jié)果.
- 還有一種更簡單的方式直接對RGBA執(zhí)行一個相同的倍數(shù)值
precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main()
{
vec4 sample0 = texture2D(colorMap, varyTextCoord);
gl_FragColor = sample0 * 1.5;
}
對比度調(diào)節(jié)
圖像對比度描述了顏色值相對于灰度值的突出程度。當(dāng)計算圖像中的對比度時,可將50%的灰度圖作為基圖像
vec3(0.5, 0.5, 0.5)
在進(jìn)行插值計算值, 原圖所占的分量越大, 則灰度越少, 對比度越明顯, 即ut小于1, 將個顏色分量越接近0.5, 降低圖像對比度; 大于1將顏色分量遠(yuǎn)離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);
}

反像
反像操作針對圖像的“負(fù)”數(shù)據(jù)的工作方式進(jìn)行建模,從白色中減去各像素的顏色值即可獲得反像,如下所示:
vec3(1.0,1.0, 1.0) - color.rgb
基于負(fù)像的片元著色器代碼,分別創(chuàng)建了某一顏色值及其負(fù)值。隨后,可用變量uT對其進(jìn)行混合。uT= 1處表示原始顏色值,uT= 0處則表示負(fù)值。
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);
}
