如何使用滑块控件调整位图的亮度?
How to use a slider control to adjust the brightness of a Bitmap?
我正在尝试调整 RGB 值以使我的图像处理器项目中的图片变暗或变亮。最好在一个 TrackBar 控件上结合变暗和变亮,当滑块在中间设置为 0 时,中性的、不变的图像。
但是,我目前仍在尝试弄清楚如何在一个 TrackBar 上只执行一项功能,例如变暗。
将 TrackBar 控件 (Min 0, Max 10
) 放入我的项目后,我使用 trackbar_scroll
事件检测 TrackBar 何时滚动。
我还对其进行了编码,通过从图像每个像素的 RGB 中减去某个字节值来使图像变暗。
当您向右滑动滚动条时,滚动条成功地使图像变暗,但是当您将 TrackBar 向左滑动回到其原始位置时,我也想取消它的变暗。
private void trbBrightness_Scroll(object sender, EventArgs e)
{
if (bitmapImage == null) return;
Byte Red, Green, Blue;
int iWidth = 320;
int iHeight = 240;
for (int i = 0; i < iWidth; i++)
{
for (int j = 0; j < iHeight; j++)
{
Color pixel = ImageArray[i, j];
Red = pixel.R;
Green = pixel.G;
Blue = pixel.B;
Color newColor =
Color.FromArgb(255,
Red - Convert.ToByte(Red * (trbBrightness.Value * 0.1)),
Green - Convert.ToByte(Green * (trbBrightness.Value * 0.1)),
Blue - Convert.ToByte(Blue * (trbBrightness.Value * 0.1)));
ImageArray[i, j] = newColor;
现在它只是像我想要的那样使图像变暗,但是我希望,当向左滑动时,滑块向右滑动时基本上可以取消变暗。
有没有办法检测滑块的值何时增加,执行此操作,以及滑块值何时减少,执行此操作?
我假设我必须以某种方式存储旧的 trackbar 值,以便我可以将它与新的进行比较?
我在哪里可以得到:
if (trackbar value is increasing)
{
}
else if (trackbar value is decreasing)
{
}
您只需要保证原始位图的安全并在调整值时应用 ColorMatrix to the original bitmap ImageAttributes。
当然,您不能调整已经调整过的内容,否则,您将永远无法恢复到源位图的原始 Brightness/Contrast 值。
将新值设置为原始位图,然后仅显示结果,保留原始值。
对比度组件的设置范围为 -1.00f
到 2.00f
。
当对比度值低于 0
时,您正在反转颜色以制作 负片 图像。您需要决定是否允许这种行为。否则,您可以将对比度限制为最小 0.00f
:应用于所有颜色分量,生成灰色 blob(完全没有对比度)。
亮度组件的值可以设置在-1.00f
到+1.00f
的范围内。上面和下面你有全白和全黑的结果。
使用恒等矩阵作为参考:
C = Contrast = 1
: B = Brightness = 0
C, 0, 0, 0, 0 1, 0, 0, 0, 0
0, C, 0, 0, 0 0, 1, 0, 0, 0
0, 0, C, 0, 0 0, 0, 1, 0, 0
0, 0, 0, 1, 0 0, 0, 0, 1, 0
B, B, B, 1, 1 0, 0, 0, 1, 1
(如果你习惯了Matrix的math定义或者其他平台定义它的方式,你可能会认为这是错误的。这只是ColorMatrix的定义方式在.Net/GDI 方言).
调整位图亮度和对比度所需的代码示例,使用 ColorMatrix 和标准 PictureBox 控件来显示结果。
样本结果:
程序:
将 Image 分配给 PictureBox 控件,然后将相同的 Image 分配给 Bitmap 对象,这里是一个名为 adjustBitmap
:
的字段
Bitmap adjustBitmap = null;
在某处(Form.Load()
,也许),将图像分配给 PicureBox,并将同一图像的副本分配给 adjustBitmap
字段,这将保留原始图像颜色值。
注意:Dispose()
的adjustBitmap
对象当Form关闭(Form.FormClosed
)事件。
添加 2 个 TrackBar 控件,一个用于调整亮度,一个用于对比度(名为 trkContrast
和 trkBrightness
这里).
亮度 轨迹栏将具有:Minimum = -100, Maximum = 100, Value = 0
对比度 轨迹栏将具有:Minimum = -100, Maximum = 200, Value = 100
订阅并分配给 Scroll
事件的同一事件处理程序。
处理程序代码调用负责调整位图亮度和对比度的方法,使用 2 个 TrackBar 控件的当前值和原始位图的引用:
// Somewhere... assign the Bitmap to be altered to the Field
adjustBitmap = [Some Bitmap];
// Use a copy of the above as the PictureBox image
pictureBox1.Image = [A copy of the above];
private void trackBar_Scroll(object sender, EventArgs e)
{
pictureBox1.Image?.Dispose();
pictureBox1.Image = AdjustBrightnessContrast(adjustBitmap, trkContrast.Value, trkBrightness.Value);
}
主要方法将 TrackBars 的 int
值转换为前面描述的范围内的浮点数,然后分配给矩阵数组:
新的 ColorMatrix
被分配给一个 ImageAttribute
class,它在Graphics.DrawImage 接受 ImageAttribute
.
的方法重载
using System.Drawing;
using System.Drawing.Imaging;
public Bitmap AdjustBrightnessContrast(Image image, int contrastValue, int brightnessValue)
{
float brightness = -(brightnessValue / 100.0f);
float contrast = contrastValue / 100.0f;
var bitmap = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb));
using (var g = Graphics.FromImage(bitmap))
using (var attributes = new ImageAttributes())
{
float[][] matrix = {
new float[] { contrast, 0, 0, 0, 0},
new float[] {0, contrast, 0, 0, 0},
new float[] {0, 0, contrast, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {brightness, brightness, brightness, 1, 1}
};
ColorMatrix colorMatrix = new ColorMatrix(matrix);
attributes.SetColorMatrix(colorMatrix);
g.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height),
0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, attributes);
return bitmap;
}
}
我正在尝试调整 RGB 值以使我的图像处理器项目中的图片变暗或变亮。最好在一个 TrackBar 控件上结合变暗和变亮,当滑块在中间设置为 0 时,中性的、不变的图像。
但是,我目前仍在尝试弄清楚如何在一个 TrackBar 上只执行一项功能,例如变暗。
将 TrackBar 控件 (Min 0, Max 10
) 放入我的项目后,我使用 trackbar_scroll
事件检测 TrackBar 何时滚动。
我还对其进行了编码,通过从图像每个像素的 RGB 中减去某个字节值来使图像变暗。
当您向右滑动滚动条时,滚动条成功地使图像变暗,但是当您将 TrackBar 向左滑动回到其原始位置时,我也想取消它的变暗。
private void trbBrightness_Scroll(object sender, EventArgs e)
{
if (bitmapImage == null) return;
Byte Red, Green, Blue;
int iWidth = 320;
int iHeight = 240;
for (int i = 0; i < iWidth; i++)
{
for (int j = 0; j < iHeight; j++)
{
Color pixel = ImageArray[i, j];
Red = pixel.R;
Green = pixel.G;
Blue = pixel.B;
Color newColor =
Color.FromArgb(255,
Red - Convert.ToByte(Red * (trbBrightness.Value * 0.1)),
Green - Convert.ToByte(Green * (trbBrightness.Value * 0.1)),
Blue - Convert.ToByte(Blue * (trbBrightness.Value * 0.1)));
ImageArray[i, j] = newColor;
现在它只是像我想要的那样使图像变暗,但是我希望,当向左滑动时,滑块向右滑动时基本上可以取消变暗。
有没有办法检测滑块的值何时增加,执行此操作,以及滑块值何时减少,执行此操作?
我假设我必须以某种方式存储旧的 trackbar 值,以便我可以将它与新的进行比较?
我在哪里可以得到:
if (trackbar value is increasing)
{
}
else if (trackbar value is decreasing)
{
}
您只需要保证原始位图的安全并在调整值时应用 ColorMatrix to the original bitmap ImageAttributes。
当然,您不能调整已经调整过的内容,否则,您将永远无法恢复到源位图的原始 Brightness/Contrast 值。
将新值设置为原始位图,然后仅显示结果,保留原始值。
对比度组件的设置范围为 -1.00f
到 2.00f
。
当对比度值低于 0
时,您正在反转颜色以制作 负片 图像。您需要决定是否允许这种行为。否则,您可以将对比度限制为最小 0.00f
:应用于所有颜色分量,生成灰色 blob(完全没有对比度)。
亮度组件的值可以设置在-1.00f
到+1.00f
的范围内。上面和下面你有全白和全黑的结果。
使用恒等矩阵作为参考:
C = Contrast = 1
: B = Brightness = 0
C, 0, 0, 0, 0 1, 0, 0, 0, 0
0, C, 0, 0, 0 0, 1, 0, 0, 0
0, 0, C, 0, 0 0, 0, 1, 0, 0
0, 0, 0, 1, 0 0, 0, 0, 1, 0
B, B, B, 1, 1 0, 0, 0, 1, 1
(如果你习惯了Matrix的math定义或者其他平台定义它的方式,你可能会认为这是错误的。这只是ColorMatrix的定义方式在.Net/GDI 方言).
调整位图亮度和对比度所需的代码示例,使用 ColorMatrix 和标准 PictureBox 控件来显示结果。
样本结果:
程序:
将 Image 分配给 PictureBox 控件,然后将相同的 Image 分配给 Bitmap 对象,这里是一个名为 adjustBitmap
:
Bitmap adjustBitmap = null;
在某处(Form.Load()
,也许),将图像分配给 PicureBox,并将同一图像的副本分配给 adjustBitmap
字段,这将保留原始图像颜色值。
注意:Dispose()
的adjustBitmap
对象当Form关闭(Form.FormClosed
)事件。
添加 2 个 TrackBar 控件,一个用于调整亮度,一个用于对比度(名为 trkContrast
和 trkBrightness
这里).
亮度 轨迹栏将具有:Minimum = -100, Maximum = 100, Value = 0
对比度 轨迹栏将具有:Minimum = -100, Maximum = 200, Value = 100
订阅并分配给 Scroll
事件的同一事件处理程序。
处理程序代码调用负责调整位图亮度和对比度的方法,使用 2 个 TrackBar 控件的当前值和原始位图的引用:
// Somewhere... assign the Bitmap to be altered to the Field
adjustBitmap = [Some Bitmap];
// Use a copy of the above as the PictureBox image
pictureBox1.Image = [A copy of the above];
private void trackBar_Scroll(object sender, EventArgs e)
{
pictureBox1.Image?.Dispose();
pictureBox1.Image = AdjustBrightnessContrast(adjustBitmap, trkContrast.Value, trkBrightness.Value);
}
主要方法将 TrackBars 的 int
值转换为前面描述的范围内的浮点数,然后分配给矩阵数组:
新的 ColorMatrix
被分配给一个 ImageAttribute
class,它在Graphics.DrawImage 接受 ImageAttribute
.
using System.Drawing;
using System.Drawing.Imaging;
public Bitmap AdjustBrightnessContrast(Image image, int contrastValue, int brightnessValue)
{
float brightness = -(brightnessValue / 100.0f);
float contrast = contrastValue / 100.0f;
var bitmap = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb));
using (var g = Graphics.FromImage(bitmap))
using (var attributes = new ImageAttributes())
{
float[][] matrix = {
new float[] { contrast, 0, 0, 0, 0},
new float[] {0, contrast, 0, 0, 0},
new float[] {0, 0, contrast, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {brightness, brightness, brightness, 1, 1}
};
ColorMatrix colorMatrix = new ColorMatrix(matrix);
attributes.SetColorMatrix(colorMatrix);
g.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height),
0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, attributes);
return bitmap;
}
}