GDI GetPixel() 有更快的替代方案吗?

Posted

技术标签:

【中文标题】GDI GetPixel() 有更快的替代方案吗?【英文标题】:Is there a faster alternative to GDI GetPixel()? 【发布时间】:2011-05-13 06:03:56 【问题描述】:

我在 .NET 应用程序中使用来自 gdi32.dll 的GetPixel() 对屏幕上任意位置的像素颜色进行采样。它工作正常,但对我来说是一个主要的性能瓶颈。

有没有更快的方法?

【问题讨论】:

你需要什么样的用法?在屏幕上抓取一个区域然后从中采样像素可能是值得的。 我的应用程序允许用户从屏幕上的任何位置(我的应用程序之外)实时采样颜色。 +1 关于限制到一个区域的好主意:我会看看我是否可以这样做。 【参考方案1】:

使用BitmapLockBits() 方法可以快速访问像素。这将返回一个对象,其中包含指向像素数据开头的指针,您可以使用不安全代码访问内存。

https://web.archive.org/web/20150330113356/http://bobpowell.net/lockingbits.aspx

【讨论】:

谢谢。我投了赞成票,因为这是一篇对我正在做的其他图像处理有用的文章。但这并不能帮助我获得屏幕上任何位置的像素颜色(除非我先截取屏幕截图,这不是我想要的)。【参考方案2】:

GetPixel 速度慢有两个原因:

    由于您正在轮询屏幕 - 每次调用 GetPixel 都会导致对视频驱动程序的事务处理,而视频驱动程序又会从视频内存中获取像素数据。

    相比之下,在 DIB 上使用 GetPixel 会快得多。

    无论如何GetPixel 做了几件事,包括坐标裁剪/转换等。

因此,如果您使用一次查询多个像素值 - 您应该尝试将其安排在 GDI / 视频驱动程序的单个事务中。

使用 GDI,您应该创建一个足够大小的 DIB(请参阅CreateDIBSection)。创建后,您将获得指向图像位数据的直接指针。然后将图像部分复制到您的 DIB(请参阅BitBlt)。在实际检查 DIB 的内容之前不要忘记调用GdiFlush(因为视频驱动程序可能会进行异步绘图)。

使用 GD+,您实际上可以做同样的事情,但语法更简单。

【讨论】:

以上是关于GDI GetPixel() 有更快的替代方案吗?的主要内容,如果未能解决你的问题,请参考以下文章

col.drop_duplicates() 有更快的替代方法吗?

push_back 的更快替代方案(已知大小)

Win32:是不是有使用硬件加速的替代 GDI32.dll?

iterrows 的更快替代方案

执行 pandas groupby 操作的更快替代方案

使 mysql 查询更快,或提出替代方案