在Windows 7上用Python快速获取屏幕上某些像素的颜色

发布于 2024-09-24 20:42:06 字数 770 浏览 5 评论 0原文

我需要获取屏幕上或活动窗口中某些像素的颜色,并且需要快速。我尝试过使用 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。我看了看,但不知道该怎么做。

I need to get the color of some pixels on the screen or from the active window, and I need to do so quickly. I've tried using win32gui and ctypes/windll, but they're much too slow. Each of these programs gets the color of 100 pixels:

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())

and

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())

Each of these takes about 1.75 seconds. I need a program like this to take less than 0.1 seconds. What's making it so slow?

I'm working with Python 3.x and Windows 7. If your solution requires I use Python 2.x, please link me to an article showing how to have Python 3.x and 2.x both installed. I looked, but couldn't figure out how to do this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

江湖正好 2024-10-01 20:42:06

这比一直使用 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

This is better than using getpixel all the time and works faster.

import ImageGrab

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

Reference: Image.load

胡大本事 2024-10-01 20:42:06

感谢 Margus 的指导,我在提取像素信息之前专注于获取图像。这是使用 Python 成像库 (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,我将其分成 新问题。我仍然遇到一些问题,但它通常可以工作。

Thanks to Margus' direction, I focused on getting the image before extracting the pixel information. Here's a workable solution using the Python Imaging Library (PIL), which requires 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())

I don't think it gets any simpler than that. This takes (on average) 0.1 seconds, which is a little slower than I'd like but fast enough.

As for having Python 3.x and 2.x both installed, I separated that into a new question. I'm still having some trouble with it, but it's generally working.

一口甜 2024-10-01 20:42:06

禁用 Windows 桌面组合可以加快像素读取速度很多

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

Python 2.7(对于 3.x 应该相同)

win32gui.GetPixel()     #1.75s => 20ms
ctypes.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)

Disabling Windows Desktop Composition speeds pixel up reading A LOT.

Computer -> Properties -> Advanced system settings -> Performance -> desktop composition [ ] (warning this disables Windows's transparency effects)

Python 2.7 (Should be same for 3.x)

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

AutoIt for comparison

$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)
梦旅人picnic 2024-10-01 20:42:06

我遇到了同样的问题,并解决了它(在Java中在 C# 中)。该解决方案背后的主要思想是从屏幕获取像素很慢,并且您无法修复它。但当您需要一些像素时,您可以一次获得一堆像素。

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

I had this same exact problem, and solved it (in Java, in C#). The main idea behind the solution is GetPixel from screen is slow, and you can't fix that. But as you need some pixels, you can get a bunch of them all at once.

The time that it took to get 64 pixels was 98 times faster.

生活了然无味 2024-10-01 20:42:06

尝试使用 pyautogui 库

import pyautogui

r, g, b = pyautogui.pixel(x, y)
print("The cursor is currently at: " + str(x) + ", " + str(y))

try using the pyautogui library

import pyautogui

r, g, b = pyautogui.pixel(x, y)
print("The cursor is currently at: " + str(x) + ", " + str(y))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文