色彩平衡

修图工具中的色彩平衡一般用来根据亮度等级调整图片中颜色的偏色,调整偏色涉及到加色原理和减色原理

其实我们通过三原色加色原理的图片就可以知道,红色的对比色是青色,蓝色的对比色是黄色,绿色的对比色是品红,这样说可能不太直观,其实我们只要试一下,把图片的r值整体提高,图片会偏红(废话),降低r值,图片会偏青色,g通道和b通道同理,或者,我们用白色(255, 255, 255)减去红色(255, 0, 0),,得到了(0, 255, 255)青色,实际上红色就是青色的反相,在色相环也是正对面的颜色。
为了对三个亮度进行不同程度的偏色调整,我们需要拿到一个颜色每个通道的值对应的三个亮度的权重,举个例子,一个r值为127,那么这个值的阴影调整的权重就应该比较低,中亮调整的权重应该比较高,高亮调整的权重应该比较低,那么我调整中亮的红黄拉杆的时候,对这个颜色的影响是比较大的,如果这个r值是高亮部分的(比如250),那么调整中亮的红黄拉杆对这个颜色的影响就很小(实际上是0),调整高亮的红黄拉杆影响就比较大。



可以看到,调节高亮拉杆对图片影响是比较大的,说明这幅图中r值比较高的像素较多,但是有的区域无论是调整高亮的拉杆还是调整中亮的拉杆都会被影响,这是因为三个亮度的权重并不是你一我零,色彩平衡的调整并不是把像素的值严格按三个等级区分开进行调整,只是说调整的权重有高有低

这个是接下来会讲到的权重的映射,x轴为某个通道的值,红绿蓝三种颜色分别代表阴影,中亮,高亮的权重的变化曲线

GIMP计算权重的代码

static void
color_balance_transfer_init (void)
{gint i;for (i = 0; i < 256; i++){static const gdouble a = 64, b = 85, scale = 1.785;gdouble low = CLAMP ((i - b) / -a + .5, 0, 1) * scale;gdouble mid = CLAMP ((i - b) /  a + .5, 0, 1) *CLAMP ((i + b - 255) / -a + .5, 0, 1) * scale;shadows[i]          = low;midtones[i]         = mid;highlights[255 - i] = low;}
}

这段代码是GIMP里生成三种亮度等级的权重映射,实际上映射出来的权重我们也可以用GIMP的公式单独计算出来

GLSL计算权重的代码

vec3 transfer(float value)
{const float a = 64.0, b = 85.0, scale = 1.785;vec3 result;float i = value * 255.0;float shadows = clamp ((i - b) / -a + 0.5, 0.0, 1.0) * scale;float midtones = clamp ((i - b) /  a + 0.5, 0.0, 1.0) * clamp ((i + b - 255.0) / -a + .5, 0.0, 1.0) * scale;float highlights = clamp (((255.0 - i) - b) / -a + 0.5, 0.0, 1.0) * scale;result.r = shadows;result.g = midtones;result.b = highlights;return result;
}

该映射的曲线

红色曲线为阴影的权重映射
绿色曲线为中亮的权重映射
蓝色曲线为高亮的权重映射

计算的时候将每个通道的值加上这个通道的三种亮度的权重乘上对应的拉杆值就行了
最后如果要保持亮度的话就调用一下rgb与hsl的转换函数就好,拉杆的取值范围是[-100, 100]

代码:

precision mediump float;
varying mediump vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform float cyan_red_shadow;
uniform float cyan_red_midtones;
uniform float cyan_red_highlights;uniform float magenta_green_shadow;
uniform float magenta_green_midtones;
uniform float magenta_green_highlights;uniform float yellow_blue_shadow;
uniform float yellow_blue_midtones;
uniform float yellow_blue_highlights;vec3 transfer(float value)
{const float a = 64.0, b = 85.0, scale = 1.785;vec3 result;float i = value * 255.0;float shadows = clamp ((i - b) / -a + 0.5, 0.0, 1.0) * scale;float midtones = clamp ((i - b) /  a + 0.5, 0.0, 1.0) * clamp ((i + b - 255.0) / -a + .5, 0.0, 1.0) * scale;float highlights = clamp (((255.0 - i) - b) / -a + 0.5, 0.0, 1.0) * scale;result.r = shadows;result.g = midtones;result.b = highlights;return result;
}vec3 rgb2hsl(vec3 color){vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);vec4 p = mix(vec4(color.bg, K.wz), vec4(color.gb, K.xy), step(color.b, color.g));vec4 q = mix(vec4(p.xyw, color.r), vec4(color.r, p.yzx), step(p.x, color.r));float d = q.x - min(q.w, q.y);float e = 1.0e-10;return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}//hsla转rgb
vec3 hsl2rgb(vec3 color)
{vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);vec3 p = abs(fract(color.xxx + K.xyz) * 6.0 - K.www);return color.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), color.y);
}void main()
{vec4 base = texture2D(inputImageTexture, textureCoordinate);vec3 hsl = rgb2hsl(base.rgb);vec3 weight_r = transfer(base.r);vec3 weight_g = transfer(base.g);vec3 weight_b = transfer(base.b);vec3 color = vec3(base.rgb * 255.0);color.r += cyan_red_shadow * weight_r.r;color.r += cyan_red_midtones * weight_r.g;color.r += cyan_red_highlights * weight_r.b;color.g += magenta_green_shadow * weight_g.r;color.g += magenta_green_midtones * weight_g.g;color.g += magenta_green_highlights * weight_g.b;color.b += yellow_blue_shadow * weight_b.r;color.b += yellow_blue_midtones * weight_b.g;color.b += yellow_blue_highlights * weight_b.b;color.r = clamp(color.r, 0.0, 255.0);color.g = clamp(color.g, 0.0, 255.0);color.b = clamp(color.b, 0.0, 255.0);vec3 hsl2 = rgb2hsl(color / 255.0);hsl2.z = hsl.z;gl_FragColor=vec4(hsl2rgb(hsl2), base.a);
}

GLSL 参考GIMP源码实现色彩平衡调节相关推荐

  1. jdbc查询大数据,上亿数据 不会内存溢出(参考solr源码封装)

    目标 最近公司要求做一个web版ETL工具,需要一次性查询出来任意一张表的所有的数据,有一张表到达了1亿两千万,所有经过探索采用了以下的方案 先说一下内存溢出的原因 jdbc查询mysql时,默认会一 ...

  2. Android 音频源码分析——音量调节流程

    源码分析基于android9.0 一.声音类型 对于大多数手机用户来说,操作手机音量按键可以看到,声音类型分为四种:媒体.铃声.闹钟.通话,但是其系统内部则分为十几种类型. 声⾳类型用来区分不同播放用 ...

  3. 100套java课设源码参考/毕设源码代码参考

    引言:本人是一个Java 开发者,喜欢分享Java课设源码和代码,用于课程设计或者作业学习参考噢,开发一些有技术含量的Java web源码,主要的技术有JSP+Servlet,SSM/SpringBo ...

  4. 课程项目:大学程序设计相关大作业汇总参考及源码地址

    C++程序设计 利用C++实现的小游戏:2048,俄罗斯方块和贪吃蛇[Some small games implemented in C++: 2048, Tetris and Snake (Univ ...

  5. android seekbar 源码,Android SeekBar调节音量

    [实例简介] 通过SeekBar控制系统音量,具体请查看http://blog.csdn.net/a1533588867/article/details/53738027 [实例截图] [核心代码] ...

  6. 使用Reflector 反编译 NPOI 查看源码,参考源码修改NPOI创建word 页眉中添加锚点图片

    上篇文章使用了inline方式往页眉中插入图片,因为这种方式插入的图片不好按照坐标定位方式调整图片的摆放位置,所以只能参考NPOI 源码中inline的方式修改添加CT_Anchor 锚点的方式 首先 ...

  7. HashMap 源码详细分析(JDK1.8)

    1. 概述 本篇文章我们来聊聊大家日常开发中常用的一个集合类 - HashMap.HashMap 最早出现在 JDK 1.2中,底层基于散列算法实现.HashMap 允许 null 键和 null 值 ...

  8. HashMap 源码详细分析(JDK1.8) 1

    1.概述 本篇文章我们来聊聊大家日常开发中常用的一个集合类 - HashMap.HashMap 最早出现在 JDK 1.2中,底层基于散列算法实现.HashMap 允许 null 键和 null 值, ...

  9. 【特征匹配】ORB原理与源码解析

    相关 : Fast原理与源码解析 Brief描述子原理与源码解析 Harris原理与源码解析 http://blog.csdn.net/luoshixian099/article/details/48 ...

最新文章

  1. Xamarin.Android开发实践(十七)
  2. 【逆天的算法】这几首宋词,你能看出来是出自计算机之手吗?
  3. 深入分析 iBATIS 框架之系统架构与映射原理--转载
  4. q87主板支持cpu型号_怎么选内存,看主板和CPU的支持,取一致性约束
  5. OpenGL multiple lights多光源的实例
  6. 用Quartus II Timequest Timing Analyzer进行时序分析 :实例讲解
  7. 【阿西莫夫】最后的问题
  8. 软件工程学习笔记《一》什么是软件工程
  9. fcpx插件Title Pop:78个可自定义的Final Cut Pro X动画标题+ 2个额外背景
  10. python中相对路径下文件的读取
  11. sort函数_Python排序之sortamp;sorted
  12. 如何在 Mac 上将照片导出为不同的文件格式?
  13. python 基于滑动平均思想实现缺失数据填充
  14. springboot整合mybatis-pluss、sharding-JDBC 水平分表demo
  15. 汉语转拼音和五笔简码
  16. 计算机管理储存u盘无法使用,小编教你无法格式化u盘怎么解决
  17. 用计算机找到自己的另一半,如何找到自己的另一半
  18. 0和1在计算机电路中,0和1
  19. 【机器学习】课程设计布置:某闯关类手游用户流失预测
  20. php 病案系统,医疗档案管理系统

热门文章

  1. java 读取 doc_java如何读取doc文件
  2. 国内十大优质炒白银交易app软件排名(2023精选版)
  3. Android Qcom USB Driver学习(二)
  4. Jquery-留言板
  5. 聊聊支付通道那些事儿——介绍和接入
  6. mysql根据id取模备份_MySQL中取模运算的正负与被模数的符号相同
  7. 微信复制统计系统-好多粉如何使用?
  8. 第九篇:万丈高楼平地起-驱动编程基础知识点
  9. 六步绘制漂亮思维导图简单画法
  10. redis指定配置文件启动不生效_Windows Redis默认配置文件,Redis配置不生效解决方案...