【问题标题】:Quickly getting the color of some pixels on the screen in Python on Windows 7在 Windows 7 上用 Python 快速获取屏幕上某些像素的颜色
【发布时间】:2011-04-17 13:25:44
【问题描述】:

我需要获取屏幕上或活动窗口中某些像素的颜色,我需要这样做快速。我试过使用 win32gui 和 ctypes/windll,但它们太慢了。这些程序中的每一个都获得 100 像素的颜色:

import win32gui
import time
time.clock()
for y in range(0, 100, 10):
    for x in range(0, 100, 10):
        color = win32gui.GetPixel(win32gui.GetDC(win32gui.GetActiveWindow()), x , y)
print(time.clock())

from ctypes import windll
import time
time.clock()
hdc = windll.user32.GetDC(0)
for y in range(0, 100, 10):
    for x in range(0, 100, 10):
        color = windll.gdi32.GetPixel(hdc, x, y)
print(time.clock())

每个都需要大约 1.75 秒。我需要这样的程序花费不到 0.1 秒。是什么让它这么慢?

我正在使用 Python 3.x 和 Windows 7。如果您的解决方案需要我使用 Python 2.x,请将我链接到显示如何同时安装 Python 3.x 和 2.x 的文章。我看了看,但不知道该怎么做。

【问题讨论】:

    标签: python windows-7 colors screen pixel


    【解决方案1】:

    感谢 Margus 的指导,我在提取像素信息之前专注于获取图像。这是一个使用 Python Imaging Library (PIL) 的可行解决方案,它需要 Python 2.x。

    import ImageGrab
    import time
    time.clock()
    image = ImageGrab.grab()
    for y in range(0, 100, 10):
        for x in range(0, 100, 10):
            color = image.getpixel((x, y))
    print(time.clock())
    

    我认为没有比这更简单的了。这需要(平均)0.1 秒,这比我想要的要慢一点,但足够快。

    至于同时安装了 Python 3.x 和 2.x,我将其分隔为 new question。我仍然遇到一些问题,但它通常可以正常工作。

    【讨论】:

      【解决方案2】:

      这比一直使用getpixel 更好,而且运行速度更快。

      import ImageGrab
      
      px = ImageGrab.grab().load()
      for y in range(0, 100, 10):
          for x in range(0, 100, 10):
              color = px[x, y]
      

      参考:Image.load

      【讨论】:

      • ImageGrab 仅适用于 Windows。
      • 您好,我知道这是旧的,但我想知道(0, 100, 10)for y in rangefor x in range 中的含义。我在想从哪里获取像素,但为什么会有 3 个数字?它们各自是什么意思?
      • @Mihkel:继续阅读class range(start, stop[, step])
      • @PéturIngiEgilsson 你从哪里得到的?我刚刚在 Linux 上导入了PILImageGrab
      • @YanKingYin 哥们,这条评论发表已经 5 年了。
      【解决方案3】:

      禁用 Windows 桌面合成会加快像素读取速度很多

      计算机 -> 属性 -> 高级系统设置 -> 性能 -> 桌面组合 [](警告这会禁用 Windows 的透明效果)

      Python 2.7(应该与 3.x 相同)

      win32gui.GetPixel()     #1.75s => 20ms
      windll.gdi32.GetPixel() #1.75s => 3ms (fastest)
      image.getpixel()        # 0.1s => 50ms
      px[]                    # 0.1s => 50ms
      

      AutoIt 比较

      $timer = TimerInit()
      
      For $x = 0 To 100 Step 10
          For $y = 0 To 100 Step 10
              PixelGetColor($x,$y) ;slow => 1ms
          Next
      Next
      
      ConsoleWrite("Time: " & TimerDiff($timer)/1000 & @CRLF)
      

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,并解决了它(in Javain C#)。解决方案背后的主要思想是 GetPixel from screen 很慢,你无法解决这个问题。但由于您需要一些像素,您可以一次获得一堆。

        获得 64 像素所需的时间快了 98 倍。

        【讨论】:

        • 所以听起来您建议我捕获整个屏幕(例如位图)然后从中获取像素值。这听起来可能是 Python Imaging Library (PIL)(需要 python 2.x)或 ImageMagick(我不确定它需要什么版本的 python)的工作。如果有人有建议,请随时加入。
        • 是的,基本上你需要与 .net 等效的 CopyFromScreen 方法,使用 Bitmap 类,你可以通过其坐标访问单个像素。是的,人们之前已经这样做了,您可以导入很多库,选择最适合您的库。
        猜你喜欢
        • 1970-01-01
        • 2014-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-11
        • 1970-01-01
        相关资源
        最近更新 更多