如何获得从绘制事件绘制的窗体上的像素

本文关键字:绘制 窗体 像素 事件 何获得 | 更新日期: 2023-09-27 18:02:39

我希望能够从paint事件中获得在表单上绘制的像素。我试过:

public Bitmap bmp;

之后:

bmp = new Bitmap(this.BackgroundImage);

然后我可以遍历像素

for (int x = 0; x < Width; x++)
{
    for (int y = 0; y < Height; y++)
    {
        bmp.GetPixel(x, y);
    }
}

但这不起作用,我想知道是否有人知道另一种方法。谢谢。

如何获得从绘制事件绘制的窗体上的像素

(警告:前面有粗鄙的简化!)通常你不能,因为窗口绘制的GDI目标(传统上)是显卡的帧缓冲区,你不能从它读,只能写。

(当然,在实践中可以从framebuffer中读取,但你不应该这样做,因为它不可信,因为另一个窗口可能与你的窗口重叠,或者另一个进程可能在另一个线程中绘制它;此外,在具有复合窗口管理器的现代系统(2006+)上,每个窗口绘制到屏幕外缓冲区而不是帧缓冲区,也可以从这些每个窗口缓冲区中读取,但它不是很快或优化-这就是为什么XOR绘制在Windows上的DWM中如此缓慢)

对于您的方法,我建议使用WinForms中的DrawToBitmap方法,它将重新绘制窗口到您自己的位图对象:

using(Bitmap b = new Bitmap( this.Width, this.Height )) {
    this.DrawToBitmap( b, new Rectangle( 0, 0, this.Width, this.Height ) );
    // Use LockBits here to iterate through each pixel
}

我不建议使用GetPixel/SetPixel,因为它们在位图中迭代像素时非常缓慢和低效;此外,使外环y而不是x更有效地利用CPU的缓存(因为连续的x值比连续的y值更接近内存)。

我不太明白你的问题。但是如果你想获得一个控件的像素(窗体只是一个控件),你可以使用Control.DrawToBitmap()方法,然后使用结果位图。

如果你想在一个特殊的油漆事件中发生的事情,你应该看看那里,但最终结果,在所有油漆事件被触发后,将在上面提到的位图中。

如果你已经设置了一个背景图像(你吗?),那么你可以直接使用它。