ウィンドウに変更があることを画像を使って検知する

単純に書く。
  • ターゲットのウィンドウを取得する
  • 取得したウィンドウの画像を取得する
  • 定期的に取得したウィンドウの画像を取得する
  • はじめに取得した画像とその後の画像に違いがあれば変更とみなす
ターゲットのウィンドウを取得する方法は何でもよいが、ここではUI Automationを使った。
from time import time
from time import sleep
from PIL import ImageGrab

import comtypes
from comtypes import CoCreateInstance
import comtypes.client
comtypes.client.GetModule('UIAutomationCore.dll')
from comtypes.gen.UIAutomationClient import *

uia = None
root_element = None

def init():
	global uia, root_element
	uia = CoCreateInstance(CUIAutomation._reg_clsid_, interface=IUIAutomation, clsctx=comtypes.CLSCTX_INPROC_SERVER|comtypes.CLSCTX_INPROC_HANDLER|comtypes.CLSCTX_LOCAL_SERVER|comtypes.CLSCTX_REMOTE_SERVER)
	root_element = uia.GetRootElement()

# Get elements by condition
def get(base_element, condition, scope=TreeScope_Subtree):
	elements = base_element.FindAll(scope, condition)
	return [ elements.GetElement(i) for i in range(elements.Length) ]

if __name__ == '__main__':
	import sys
	title = input('Window title: ')
	default_timeout = 5.0
	timeout = input('Timeout (in sec, default {} sec.): '.format(default_timeout))
	timeout = default_timeout if timeout == '' else float(timeout)

	init()
	img = None; img0 = None
	dt = .1

	print('[INFO] Start in 3 sec.')
	sleep(3)

	print('[INFO] Detecting a change in the window.')
	start_time= time()
	while True:
		try:
			condition = uia.CreatePropertyCondition(UIA_NamePropertyId, title)
			window = get(root_element, condition, TreeScope_Children)[0]
			rect = (window.CurrentBoundingRectangle.left, window.CurrentBoundingRectangle.top, window.CurrentBoundingRectangle.right, window.CurrentBoundingRectangle.bottom)
			img = ImageGrab.grab(rect)
			t = time() - start_time
			if img0 is None: img0 = img.copy()
			else:
				if img != img0:
					print('[INFO] The window has been refreshed in {:.02f} sec.'.format(t))
					break
			if t > timeout:
				print('[INFO] The window did not get refreshed in {:.02f} sec.'.format(timeout))
				break
			sleep(dt)
		except:
			if img is None: print('[ERROR] Window with the title does not exist.')
			else: print('[INFO] The window has been refreshed in {:.02f} sec.'.format(time()-start_time))
			break
2019/12/31 21:45
タグ