2010-09-27 88 views
8

我需要在屏幕上或从活动窗口中的一些像素的颜色,我必须这样做迅速。我试过使用win32gui和ctypes/windll,但它们太慢了。所有这些程序获取的100个像素颜色:迅速得到一些像素的颜色在Python中屏幕上的Windows 7

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的文章。我看了看,但无法弄清楚如何做到这一点。

谢谢!

回答

2

我有同样的确切问题,并解决它(in Javain C#)。解决方案背后的主要思想是从屏幕上获取GetPixel的速度很慢,而且无法解决这个问题。但是,因为你需要一些像素,你可以一次获得一大堆。

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

+0

所以,它听起来就像你苏提示我捕捉整个屏幕(比如说位图),然后从中获取像素值。这听起来像是它可能是Python图像库(PIL)(它需要python 2)的工作。x)或ImageMagick(我不确定它需要什么版本的python)。如果有人有任何建议,请随时登录。 – dln385 2010-09-27 18:45:59

+0

是的,基本上你需要使用与.net等价的CopyFromScreen方法,在Bitmap类中可以通过其坐标访问单个像素。是的,以前人们已经这样做了,并且有很多可以导入的库,选择最适合您的库。 – Margus 2010-09-27 19:21:53

8

感谢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。我仍然遇到一些麻烦,但它通常工作。

+0

注意:windows-only截至20150308 – Blauhirn 2016-03-08 01:30:03

6

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

+0

ImageGrab仅限Windows。 – 2016-12-22 17:45:02

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)