图片处理中,调节饱和度、明度、色相是非常常见的功能,这篇文章带你深入理解饱和度的调节,文末附录代码实现。
一个彩色像素由RGB组成。 明度指RGB三通道的平均值,平局值越高明度越高。 饱和度指RGB三通道中最大值与最小值之差,差别越大,饱和度越大,颜色看起来越鲜艳。
饱和度调节
明度调节
从饱和度、明度的定义来看,两个值的调节是相互影响的。参考下图,饱和度取最大值255时,就限制最大值、最小值分别为255和0,则明度值为127.5。明度值取最大值255或最小值0时,则最大值和最小值相同都是255或0,即饱和度为0。
上面介绍的是比较简单的理解,略去了细节,实际上HSV模型,是基于人的视觉感知来定义的,本没有公式计算 参考:孟塞尔颜色体系 饱和度的算法有很多种,这里介绍一种,设饱和度S的取值范围[-100, 100]。
L为明度
联系上面明度和饱和度的关系曲线,就能理解为什么以128为分界线,有两个算法
实现效果
#include"f_Saturation.h" #include<stdlib.h> #include<math.h> #include<string.h> #include<stdio.h> #include"Commen.h" int f_Saturation(unsigned char *srcData, int width, int height, int stride, int saturation) { int ret = 0; if(saturation == 0) return ret; unsigned char* pSrc = srcData; int r, g, b, rgbMin, rgbMax; saturation = CLIP3(saturation,-100,100); int k = saturation / 100.0f * 128; int alpha = 0; int offset = stride - width * 4; for(int j = 0; j < height; j++) { for(int i = 0; i < width; i++) { r = pSrc[2]; g = pSrc[1]; b = pSrc[0]; rgbMin = MIN2(MIN2(r, g), b); rgbMax = MAX2(MAX2(r, g), b); int delta = (rgbMax - rgbMin); int value = (rgbMax + rgbMin); // 饱和度为0,不处理 if(delta ==0) { pSrc += 4; continue; } int L = value >> 1; int S = L < 128 ? (delta << 7) / value : (delta << 7) / (510 - value); if(k >= 0) { alpha = k + S >= 128 ? S : 128 - k; alpha = 128 * 128 / alpha - 128; } else alpha = k; r = r + ((r - L) * alpha >> 7); g = g + ((g - L) * alpha >> 7); b = b + ((b - L) * alpha >> 7); pSrc[0] = CLIP3(b, 0, 255); pSrc[1] = CLIP3(g, 0, 255); pSrc[2] = CLIP3(r, 0, 255); pSrc += 4; } pSrc += offset; } return ret; };
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句