winforms 如何使用滑块控件来调整位图的亮度?

mkshixfv  于 2023-10-23  发布在  其他
关注(0)|答案(1)|浏览(124)

我正试图调整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;

现在它只是像我希望它变暗的图像,但我希望,当滑动左,滑块基本上撤销变暗时,你滑动它的权利。
有没有一种方法可以检测滑块的值何时增加,这样做,当滑块值减少时,这样做?
我假设我必须以某种方式存储旧的跟踪条值,以便我可以将其与新的比较?
我在哪里可以得到:

if (trackbar value is increasing) 
{

} 
else if (trackbar value is decreasing)
{

}
ct3nt3jp

ct3nt3jp1#

您只需要保持原始位图的安全,并在调整值时将ColorMatrix应用于原始位图ImageAttributes
当然,你不能调整已经调整过的内容,否则,你将永远无法回到源位图的原始亮度/对比度值。
将新值设置为原始位图,然后仅显示结果,保留原始位图。
对比度组件可以设置为-1.00f2.00f的范围。
当“对比度”值低于0时,您将反转“颜色”,从而生成 * 负 * 图像。你需要决定你是否允许这种行为。否则,您可以将对比度限制为最小值0.00f:应用于所有颜色分量,生成灰色 * 斑点 *(完全没有对比度)。
亮度分量的值可以设置为-1.00f+1.00f的范围。在上面和下面,你有全白和全黑的结果。
使用单位矩阵作为参考:
C = Contrast = 1B = 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

(If如果你习惯了Matrix的 math 定义或其他平台定义它的方式,你可能会认为它是错误的。这只是在.Net/GDI * 方言 * 中定义ColorMatrix的方式)。
调整位图的亮度和对比度所需的代码示例,使用ColorMatrix和标准PictureBox控件显示结果。

样本结果

程序

将一个Image分配给PictureBox控件,然后将同一个Image分配给Bitmap对象,这里是一个名为**adjustBitmap**的字段:

Bitmap adjustBitmap = null;

在某个地方(可能是Form.Load()),将Image分配给PicureBox,并将同一Image的副本分配给adjustBitmap Field,这将保留原始Image颜色值。

注意:Form关闭(Form.FormClosed)事件时**adjustBitmap**对象的Dispose()

添加2个TrackBar控件,一个用于调整亮度,一个用于调整对比度(此处命名为**trkContrasttrkBrightness**)。

亮度轨迹栏将具有:Minimum = -100, Maximum = 100, Value = 0
Contrast轨迹栏将具有:Minimum = -100, Maximum = 200, Value = 100

为**Scroll**事件订阅并分配相同的事件处理程序。
处理程序代码调用负责调整Bitmap的亮度和对比度的方法,使用2个TrackBar控件的当前值和原始Bitmap的引用:

// 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);
}

main方法将TrackBars的int值转换为前面描述的范围内的浮点数,然后将其赋值给Matrix数组:
新的**ColorMatrix被分配给一个ImageAttribute**类,该类用作接受ImageAttribute的Graphics.DrawImage方法重载中的参数。

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;
    }
}

相关问题