我需要使用c#降低图片的亮度。经过一些分析,我发现了一种通过调整每个像素颜色RGB值来降低图像亮度的解决方案。请从下面找到代码:
Bitmap bmp = new Bitmap(Picture);
Reduce the picture color brightness
for (int i = 0; i < bmp.Width; i++)
{
for (int j = 0; j < bmp.Height; j++)
{
Color color = bmp.GetPixel(i, j);
color = ChangeColorBrightness(color, 0.80f);
bmp.SetPixel(i, j, color);
}
}
减少特定颜色的RGB值的方法:
private Color ChangeColorBrightness(Color color, float correctionFactor)
{
float red = (float)color.R;
float green = (float)color.G;
float blue = (float)color.B;
if (correctionFactor < 0)
{
correctionFactor = 1 + correctionFactor;
red *= correctionFactor;
green *= correctionFactor;
blue *= correctionFactor;
}
else
{
red = (255 - red) * correctionFactor + red;
green = (255 - green) * correctionFactor + green;
blue = (255 - blue) * correctionFactor + blue;
}
return Color.FromArgb(color.A, (int)red, (int)green, (int)blue);
}
这个代码可以满足我的要求,但是当我执行大量宽度和高度较大的图像时需要这么长的时间。 还有其他可能性来实现这一要求吗?
答案 0 :(得分:1)
.GetPixel()
和.SetPixel()
价格昂贵 - 这是一个更快的appraoch
public static Bitmap ChangeColorBrightness(Bitmap bmp, float correctionFactor)
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
float correctionFactortemp = correctionFactor;
if (correctionFactor < 0)
{
correctionFactortemp = 1 + correctionFactor;
}
for (int counter = 1; counter < rgbValues.Length; counter ++)
{
float color = (float)rgbValues[counter];
if (correctionFactor < 0)
{
color *= (int)correctionFactortemp;
}
else
{
color = (255 - color) * correctionFactor + color;
}
rgbValues[counter] = (byte)color;
}
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
bmp.UnlockBits(bmpData);
return bmp;
}