WPF图像处理程序,包括亮度、饱和度、对比度、Gamma调节。
// Lightness Adjust
public static void BitmapLightnessAdjust(Bitmap curBitmap, int width, int height, int delta)
{
if (delta == 0)
{
return;
}
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = width * height * 4;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
if (delta > 0)
{
for (int i = 0; i < rgbValues.Length; i = i + 4)
{
rgbValues[i] = (byte)Math.Min(255, rgbValues[i] + delta);
rgbValues[i + 1] = (byte)Math.Min(255, rgbValues[i + 1] + delta);
rgbValues[i + 2] = (byte)Math.Min(255, rgbValues[i + 2] + delta);
}
}
else
{
for (int i = 0; i < rgbValues.Length; i = i + 4)
{
rgbValues[i] = (byte)Math.Max(0, rgbValues[i] + delta);
rgbValues[i + 1] = (byte)Math.Max(0, rgbValues[i + 1] + delta);
rgbValues[i + 2] = (byte)Math.Max(0, rgbValues[i + 2] + delta);
}
}
Marshal.Copy(rgbValues, 0, ptr, bytes);
curBitmap.UnlockBits(bmpData);
}
// Saturation Adjust
public static void BitmapSaturationAdjust(Bitmap curBitmap, int width, int height, int delta)
{
if (delta == 0)
{
return;
}
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = width * height * 4;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
for (int i = 0; i < rgbValues.Length; i = i + 4)
{
if (rgbValues[i] > 128)
{
rgbValues[i] = (byte)Math.Min(255, rgbValues[i] + delta);
}
else
{
rgbValues[i] = (byte)Math.Max(0, rgbValues[i] - delta);
}
if (rgbValues[i + 1] > 128)
{
rgbValues[i + 1] = (byte)Math.Min(255, rgbValues[i + 1] + delta);
}
else
{
rgbValues[i + 1] = (byte)Math.Max(0, rgbValues[i + 1] - delta);
}
if (rgbValues[i + 2] > 128)
{
rgbValues[i + 2] = (byte)Math.Min(255, rgbValues[i + 2] + delta);
}
else
{
rgbValues[i + 2] = (byte)Math.Max(0, rgbValues[i + 2] - delta);
}
}
Marshal.Copy(rgbValues, 0, ptr, bytes);
curBitmap.UnlockBits(bmpData);
}
// Contrast Adjust
public static void BitmapContrastAdjust(Bitmap curBitmap, int width, int height, int delta)
{
if (delta == 0)
{
return;
}
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = width * height * 4;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
if (delta > 0)
{
for (int i = 0; i < rgbValues.Length; i = i + 4)
{
if (rgbValues[i] > 128 && rgbValues[i + 1] > 128 && rgbValues[i + 2] > 128)
{
rgbValues[i] = (byte)Math.Min(255, rgbValues[i] + delta);
rgbValues[i + 1] = (byte)Math.Min(255, rgbValues[i + 1] + delta);
rgbValues[i + 2] = (byte)Math.Min(255, rgbValues[i + 2] + delta);
}
if (rgbValues[i] < 128 && rgbValues[i + 1] < 128 && rgbValues[i + 2] < 128)
{
rgbValues[i] = (byte)Math.Max(0, rgbValues[i] - delta);
rgbValues[i + 1] = (byte)Math.Max(0, rgbValues[i + 1] - delta);
rgbValues[i + 2] = (byte)Math.Max(0, rgbValues[i + 2] - delta);
}
}
}
else
{
for (int i = 0; i < rgbValues.Length; i = i + 4)
{
if (rgbValues[i] > 128 && rgbValues[i + 1] > 128 && rgbValues[i + 2] > 128)
{
rgbValues[i] = (byte)Math.Max(128, rgbValues[i] + delta);
rgbValues[i + 1] = (byte)Math.Max(128, rgbValues[i + 1] + delta);
rgbValues[i + 2] = (byte)Math.Max(128, rgbValues[i + 2] + delta);
}
if (rgbValues[i] < 128 && rgbValues[i + 1] < 128 && rgbValues[i + 2] < 128)
{
rgbValues[i] = (byte)Math.Min(128, rgbValues[i] - delta);
rgbValues[i + 1] = (byte)Math.Min(128, rgbValues[i + 1] - delta);
rgbValues[i + 2] = (byte)Math.Min(128, rgbValues[i + 2] - delta);
}
}
}
Marshal.Copy(rgbValues, 0, ptr, bytes);
curBitmap.UnlockBits(bmpData);
}
// Gamma Adjust
public static void BitmapGammaAdjust(Bitmap curBitmap, int width, int height, double delta)
{
if (delta == 1)
{
return;
}
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = width * height * 4;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
for (int i = 0; i < rgbValues.Length; i = i + 4)
{
rgbValues[i] = (byte)Math.Min(255, (int)Math.Round(255 * Math.Pow(rgbValues[i] / 255.0, delta)));
rgbValues[i + 1] = (byte)Math.Min(255, (int)Math.Round(255 * Math.Pow(rgbValues[i + 1] / 255.0, delta)));
rgbValues[i + 2] = (byte)Math.Min(255, (int)Math.Round(255 * Math.Pow(rgbValues[i + 1] / 255.0, delta)));
}
Marshal.Copy(rgbValues, 0, ptr, bytes);
curBitmap.UnlockBits(bmpData);
}