我希望能够从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);
}
}
但是这不起作用,我想知道是否有人知道另一种方法。 感谢。
答案 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事件被触发后的最终结果将在上面提到的位图中。
如果您确实设置了背景图片(是吗?),那么您可以直接使用它。