屏幕截图转换为灰度不起作用。是什么原因造成的?

Screenshot conversion into grayscale doesn't work. What causes this?

我有一个 Windows Forms 应用程序,它截取屏幕特定部分的屏幕截图,然后将其显示在图片框 (pictureBox1) 中。当我不尝试转换它时它会起作用,但我想将图像转换为灰度或黑白。问题是当我把它转换成灰度时,它仍然在图片框中显示原始图片。

这是运行时的代码,没有转换:

private void button1_Click(object sender, EventArgs e)
{
        Rectangle rectangle = new Rectangle(660, 200, 600, 100);
        pictureBox1.Height = rectangle.Height;
        pictureBox1.Width = rectangle.Width;

        imageUploader(rectangle);
}

public void imageUploader(Rectangle rectangle)
{
        Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppArgb);
        Graphics graphics = Graphics.FromImage(bitmap);
        graphics.CopyFromScreen(rectangle.Left, rectangle.Top, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);

        bitmap.Save("proba.jpeg", ImageFormat.Jpeg);

        pictureBox1.Image = bitmap;
} 

这里是我试过的转换方法:

public void toGrayscale(Bitmap bitmap)
    {
        Color c;

        for (int y = 0; y < bitmap.Height; y++)
        {
            for (int x = 0; x < bitmap.Width; x++)
            {
                c = bitmap.GetPixel(x,y);
                Color newColor = Color.FromArgb(c.R,0,0);
                bitmap.SetPixel(x,y,newColor);
            }
        }
    }

使用此转换后(见下文)图像出现在图片框中,但不是灰度图像。

这里是修改后的 imageUploader 无效转换:

    public void imageUploader(Rectangle rectangle)
    {
        Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppArgb);
        toGrayscale(bitmap);
        Graphics graphics = Graphics.FromImage(bitmap);
        graphics.CopyFromScreen(rectangle.Left, rectangle.Top, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);

        bitmap.Save("proba.jpeg", ImageFormat.Jpeg);

        pictureBox1.Image = bitmap;
    } 

您正在将空位图转换为灰度,然后用屏幕上的图像复制(名义上)灰度位图。这是您的代码,注释描述了它在做什么:

// This line creates an empty Bitmap.
Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppArgb);
// This line converts the empty Bitmap to grayscale.
toGrayscale(bitmap);
// This line creates a Graphics drawing surface from your bitmap.
Graphics graphics = Graphics.FromImage(bitmap);
// This line overwrites the image data from your bitmap with an image from the screen.
graphics.CopyFromScreen(rectangle.Left, rectangle.Top, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);

你需要想办法把你从屏幕上得到的数据变成灰度。你没有这样做。您已经制作了一个灰度图像,但随后通过在其上写入其他数据而将其丢弃。碰巧替换数据不是灰度。

您的问题似乎出在这里:

    public void imageUploader(Rectangle rectangle)
    {
        Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppArgb);
        toGrayscale(bitmap);
        Graphics graphics = Graphics.FromImage(bitmap);
        graphics.CopyFromScreen(rectangle.Left, rectangle.Top, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);

        bitmap.Save("proba.jpeg", ImageFormat.Jpeg);

        pictureBox1.Image = bitmap;
    }

您正在将位图的每个像素转换为灰度(奇怪的是,看起来您只抓住了红色通道)然后从屏幕上复制,这会覆盖您的转换。要修复它,您需要做的就是在从屏幕复制后移动 toGreyscale,如下所示:

    public void imageUploader(Rectangle rectangle)
    {
        Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppArgb);
        Graphics graphics = Graphics.FromImage(bitmap);
        graphics.CopyFromScreen(rectangle.Left, rectangle.Top, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);
        toGrayscale(bitmap);  # Moved after the copy from screen
        bitmap.Save("proba.jpeg", ImageFormat.Jpeg);

        pictureBox1.Image = bitmap;
    }

这应该可以解决问题。