主要思想: 也是将RGB转换为HSL色彩空间然后再调节其S,但是加了补偿。 之前直接将RGB转换HSl再调整S之后再换回RGB,发现不仅效果不明显,反而一下子就出现色斑了。 当然可以直接用DLL,比如ImageProcessor,可以直接用image类型来调整。
public void AdjustSaturationByIF(Image MImage,int degree)
{
// 只调整图像的饱和度值
ImageFactory imageF = new ImageFactory();
imageF.Load(MImage);
imageF.Saturation(degree);
...
}
图像的饱和度调整有很多方法,最简单的就是判断每个象素的R、G、B值是否大于或小于128,大于加上调整值,小于则减去调整值;也可将象素RGB转换为HSV或者HSL,然后调整其S部分,从而达到线性调整图象饱和度的目的。这几种方法我都测试过,效果均不太好,简单的就不说了,利用HSV和HSL调整饱和度,其调节范围很窄,饱和度没达到,难看的色斑却出现了。而Photoshop的饱和度调整调节范围大多了,效果也好多了。 算法参考:CSDN博主「阿发伯」的Photoshop饱和度调整
public static void Swap(ref int a,ref int b)
{
a += b;
b = a - b;
a -= b;
}
public static void Check(ref int Value)
{
if (Value < 0) Value = 0;
else if (Value > 255) Value = 255;
}
public static void AssignRGB(out int R, out int G, out int B ,int r,int g,int b)
{
R = r;
G = g;
B = b;
}
public static void SetRGB2HSB(ref int R, ref int G, ref int B, int degree)
{
degree = degree * 255 / 100;
int rgbMax = R;
int rgbMin = G;
int rgbC = B;
if (rgbMax < rgbC) Swap(ref rgbMax, ref rgbC);
if (rgbMax < rgbMin) Swap(ref rgbMax, ref rgbMin);
if (rgbMin > rgbC) Swap(ref rgbMin, ref rgbC);
int delta = rgbMax - rgbMin;
int H, S;
int value = rgbMax + rgbMin;
int L = (value + 1) >> 1;
if (delta == 0) H = S = 0;
else
{
if (L < 128) S = delta * 255 / value;
else S = delta * 255 / (510 - value);
if (rgbMax == R) H = (G - B) * 60 / delta;
else if (rgbMax == G) H = (B - R) * 60 / delta + 120;
else H = (R - G) * 60 / delta + 240;
if (H < 0) H += 360;
H /= 60;
if (degree != 0)
{
if (degree > 0)
{
degree = degree + S >= 255 ? S : 255 - degree;
degree = 65025 / degree - 255;
}
rgbMax = rgbMax + (rgbMax - L) * degree / 255;
rgbMin = rgbMin + (rgbMin - L) * degree / 255;
rgbC = rgbC + (rgbC - L) * degree / 255;
}
}
Check(ref rgbMax);
Check(ref rgbMin);
Check(ref rgbC);
if (S != 0) AssignRGB(out R, out G, out B, rgbMax, rgbC, rgbMin);
}
public void AdjustSaturationPS(System.Drawing.Image image, int degree)
{
int[] RGB = new int[3];
Bitmap bitmap = new Bitmap(image);
BitmapData data = bitmap.LockBits(new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
if (degree < 0) degree = 0;
unsafe
{
byte* ptr = (byte*)(data.Scan0);
for (int i = 0; i < data.Height; i++)
{
for (int j = 0; j < data.Width; j++)
{
for (int k = 0; k < 3; k++)
{
RGB[k] = ptr[k];
}
SetRGB2HSB(ref RGB[0],ref RGB[1],ref RGB[2],degree);
for (int k = 0; k < 3; k++)
{
ptr[k] = (byte)RGB[k];
}
ptr += 3;
}
ptr += data.Stride - data.Width * 3;
}
}
bitmap.UnlockBits(data);
...
}