如何获取从paint事件中绘制的表单上的像素?

时间:2014-05-10 20:47:39

标签: c# forms pixels

我希望能够从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);
    }
}

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

2 个答案:

答案 0 :(得分:1)

(警告:未来大致简化!)通常你不能,因为窗口绘画的GDI目标(传统上)是图形卡的帧缓冲,你无法从中读取,只能写入它。

(当然,在实践中可以从帧缓冲区读取,但你不应该因为它不可信任,因为另一个窗口可能与你的窗口重叠,或者另一个进程可能在另一个线程中绘制它;在现代系统(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值。)

答案 1 :(得分:0)

我不确定我理解你的问题。但是如果你想获得一个Control的像素(并且一个表单只是一个控件),你可以使用Control.DrawToBitmap()方法,然后使用生成的位图。

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

如果您确实设置了背景图片(是吗?),那么您可以直接使用它。