web-dev-qa-db-ja.com

Windows7のPythonで、画面上のいくつかのピクセルの色をすばやく取得する

画面上またはアクティブなウィンドウからいくつかのピクセルの色を取得する必要があり、そうする必要がありますすばやく 。 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とWindows7を使用しています。ソリューションでPython 2.xを使用する必要がある場合は、その方法を示す記事にリンクしてください。 Python 3.xと2.xの両方がインストールされていること。調べましたが、これを行う方法がわかりませんでした。

ありがとう!

12
dln385

私はこれとまったく同じ問題を抱えていて、それを解決しました( Javaの場合C#の場合 )。ソリューションの背後にある主なアイデアは、画面からのGetPixelが遅いことであり、それを修正することはできません。しかし、いくつかのピクセルが必要なため、一度にたくさんのピクセルを取得できます。

64ピクセルを取得するのにかかった時間は98倍速かった。

2
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の両方がインストールされていることに関しては、それを 新しい質問 に分けました。まだ問題がありますが、一般的に機能しています。

9
dln385

これは、常に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

7
Oleh Prypin

Windowsデスクトップコンポジションを無効にすると、ピクセルの読み取りが高速化されますA LOT

コンピューター->プロパティ->システムの詳細設定->パフォーマンス->デスクトップ構成[](これは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)
3
Jaakko