【问题标题】:How can reduce image brightness? [duplicate]如何降低图像亮度? [复制]
【发布时间】:2016-10-11 11:25:10
【问题描述】:

我需要使用 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);
    }

这些代码可以很好地满足我的要求,但是当我执行大量具有更大宽度和高度的图像时,它会花费大量时间。 是否有其他可能实现这一要求?

【问题讨论】:

  • 与其设置每个像素,不如通过您需要的调整将图像重新绘制到新的像素上。 This answer 展示了如何在一张照片中调整亮度、对比度和伽玛。
  • 感谢您的建议。但我不喜欢在我的实现中使用 Graphics 对象。所以我忽略了使用颜色矩阵的方式。

标签: c# .net graphics


【解决方案1】:

.GetPixel().SetPixel() 很昂贵 - 这里有一个更快的方法

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

【讨论】:

  • 我不喜欢在我的实现中使用图形对象。没有图形对象有什么可能吗?
  • @VijayR,就像你在问,“什么是最快的方法来做到这一点,但不要告诉我最常见的快速方法”
  • 推荐的方法是使用颜色矩阵。使用 Winforms 图形通常意味着一个 Graphics 对象。不“喜欢”是不合理的。在这个解决方案中,尽管完全没有必要使用 Graphics 对象,而且什么也不做。
  • @TaW 你是对的,删除了
猜你喜欢
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多