【问题标题】:Even faster reading desktop color info更快地读取桌面颜色信息
【发布时间】:2016-01-18 19:47:54
【问题描述】:

有什么方法可以比我写的更快地读取颜色?

class MyApi:
    def __init__(self):
        self.width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
        self.height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
        self.left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
        self.top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
        self.hwin = win32gui.GetDesktopWindow()
        self.hwindc = win32gui.GetWindowDC(self.hwin)
        self.srcdc = win32ui.CreateDCFromHandle(self.hwindc)

        self.memdc = self.srcdc.CreateCompatibleDC()

        self.bmp = win32ui.CreateBitmap()
        self.bmp.CreateCompatibleBitmap(self.srcdc, self.width, self.height)
        self.memdc.SelectObject(self.bmp)

    def get_xy_color(self, *args):
        self.memdc.BitBlt((0, 0), (self.width, self.height), self.srcdc, (self.left, self.top), win32con.SRCCOPY)
        bmp = self.bmp.GetBitmapBits(False)
        # colors = []
        # for pixel in args:
        #     tmp = (pixel[1] * self.width + pixel[0]) * 4
        #     colors += [255 + c if c < 0 else c for c in bmp[tmp:tmp+3]][::-1]
        # return colors

未注释的get_xy_color 部分大约需要0.11 ms - 对于我的目的来说太长了。可以更快吗?

BitBlt 非常快,但 GetBitmapBits 需要很长时间。
我也可以说我不需要整个屏幕信息,如果我能得到其中的一部分,我会很高兴,例如从点 (100, 100)(150, 150)

目的是为流光溢彩项目每秒至少获得 30 次颜色。

【问题讨论】:

  • 应该迁移到 Code Review 吗?
  • 这对Code Review 来说可能是个好问题,只要:(A) 代码有效和(B ) 这绝不是假设性的或不完整的。发帖前请阅读on-topic guide,如果你选择去Code Review。如果您有任何问题或疑虑,请通过CR Help Desk 加入我们。
  • “这对我的目的来说太长了” - 那么,你的目的是什么?在不知道您要解决的问题的情况下,我们无法推荐解决方案。
  • 所以对我来说建议将问题迁移到 CodeRevies,但是这个stackoverflow.com/questions/34872664/… 问题已迁移到 SO。我认为这种困境几乎是一样的。甚至我更适合,因为我要求更快的东西(我知道有更快的东西)并且在提到的问题中只有两种方法的比较。很奇怪。
  • 我建议你清楚地描述你想要完成的事情。你写了环境光项目。颜色应该来自哪里?我的第一种方法是从屏幕边框获取视图样本。也许在 hdc 0 上调用几个 GetPixel 就足够了。

标签: python windows winapi hwnd


【解决方案1】:

你去看看:

    self.bmp = win32ui.CreateBitmap()
    self.bmp.CreateCompatibleBitmap(self.srcdc, self.width, 80)
    self.memdc.SelectObject(self.bmp)

def get_xy_color(self, left, right):
    self.memdc.BitBlt((0, -500), (self.width, 580), self.srcdc, (self.left, self.top), win32con.SRCCOPY)
    bmp = self.bmp.GetBitmapBits(False)

这将集中在屏幕高度和全宽 500 到 500 像素之间的一条线上。我只是不知道我可以使用负值。我已经通过将位图保存为文件并寻求好的解决方案来检查如何做到这一点。

现在我不处理整个屏幕并将时间减少到 10 到 20 毫秒之间。这对我来说是完美的结果。

代码的目的是用于流光溢彩项目。颜色正在通过串行端口发送到 Arduino,Arduino 将其处理为 LED 颜色。

有了这个解决方案,我可以对 Arduino 进行 39 到 60 次获取和发送 - 效果很好。

【讨论】:

  • 这就是我的意思:您从未对您的问题提供充分的解释,也没有提供解决方案的简洁说明。我很确定您可以将DWM Thumbnails 用于您的目的。高度优化的代码,内置于系统中。过滤是免费的。
  • 我见过使用 DWM 完成这项工作的零解决方案。我什至见过劝阻 DWM 的人。你能提供什么特别的东西吗?
  • 您的GetBitmapBits 到底是做什么的? win32 函数GetBitmapBits 已弃用,替换为GetDIBits 复制似乎没有必要的位图数据,因为您已经拥有自己的位图。
  • 如果您能提供一些如何使用 GetDIBits 的示例,那就太好了,因为我找不到自己。
  • 我在这里找到了示例:nullege.com/codes/show/src@m@s@mss-0.0.7@mss.py/701/…(第 701 行),但它返回给我一个这样的数组:&lt;?A&lt;?A&lt;?A&lt;?A&lt;?A&lt;?A(((&lt;?A&lt;?A&lt;?Az\x80\x84UZ\\UZ\\UZ\\\x87\x87\x87UZ\\UZ\\UZ\\UZ\\UZ\\UZ\\UZ\\UZ\\\xa2x\xba\xab\x82\xc1 等。检索整个屏幕需要将近 4 秒。
猜你喜欢
  • 2017-12-23
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 2014-05-12
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
  • 2015-11-03
相关资源
最近更新 更多