如何用python讀取視窗影像有四種方法:
首先要查詢有哪些程式執行中,列出
方法一
import win32gui
hwnd_title = dict()
def get_all_hwnd(hwnd,mouse):
if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
hwnd_title.update({hwnd:win32gui.GetWindowText(hwnd)})
win32gui.EnumWindows(get_all_hwnd, 0)
for h,t in hwnd_title.items():
if t is not "":
print(h, t)
以上可以列出windows 正在執行的程式…
方法二
def winEnumHandler( hwnd, ctx ):
if win32gui.IsWindowVisible( hwnd ):
print (hex(hwnd), win32gui.GetWindowText( hwnd ))
win32gui.EnumWindows( winEnumHandler, None )
1.ImageGrab
找出視窗位置,然後用截圖方法
import time
import numpy as np
from PIL import ImageGrab
img = ImageGrab.grab(bbox=(100, 161, 1141, 610))
img = np.array(img.getdata(), np.uint8).reshape(img.size[1], img.size[0], 3)
2.winAPI
hwin = win32gui.GetDesktopWindow()
if region:
left,top,x2,y2 = region
width = x2 - left + 1
height = y2 - top + 1
else:
width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
hwindc = win32gui.GetWindowDC(hwin)
srcdc = win32ui.CreateDCFromHandle(hwindc)
memdc = srcdc.CreateCompatibleDC()
bmp = win32ui.CreateBitmap()
bmp.CreateCompatibleBitmap(srcdc, width, height)
memdc.SelectObject(bmp)
memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY)
signedIntsArray = bmp.GetBitmapBits(True)
img = np.fromstring(signedIntsArray, dtype='uint8')
img.shape = (height,width,4)
srcdc.DeleteDC()
memdc.DeleteDC()
win32gui.ReleaseDC(hwin, hwindc)
win32gui.DeleteObject(bmp.GetHandle())
return cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)
3.pyqt5 擷取,這個最好用速度最快
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import *
import win32gui
import sys
def convertQImageToMat(incomingImage):
''' Converts a QImage into an opencv MAT format '''
# Format_RGB32 = 4,存入格式為B,G,R,A 對應 0,1,2,3
# RGB32圖像每個像素用32比特位表示,占4個字節,
# R,G,B分量分別用8個bit表示,存儲順序為B,G,R,最後8個字節保留
incomingImage = incomingImage.convertToFormat(4)
width = incomingImage.width()
height = incomingImage.height()
ptr = incomingImage.bits()
ptr.setsize(incomingImage.byteCount())
arr = np.array(ptr).reshape(height, width, 4) # Copies the data
# arr為BGRA,4通道圖片
return arr
hwnd = win32gui.FindWindow(None, 'OBS 27.2.0-rc4 (64-bit, windows) - Profile: profile_backup - Scenes: 無標題 2')
app = QApplication(sys.argv)
screen = QApplication.primaryScreen()
while True:
img = screen.grabWindow(hwnd).toImage()
img=convertQImageToMat(img)#將獲取的圖像從QImage轉換為RBG格式
cv2.imshow("asd",img) #imshow
k = cv2.waitKey(30)&0xFF #64bits! need a mask
if k ==27:
cv2.destroyAllWindows()
break
4.pyautogui
pyautogui是比較簡單的,但是不能指定獲取程序的窗口,因此窗口也不能遮擋,不過可以指定截屏的位置,0.04s一張截圖,比PyQt稍慢一點,但也很快了。
import pyautogui
import cv2
img = pyautogui.screenshot(region=[0,0,100,100]) # x,y,w,h
# img.save('screenshot.png')
img = cv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR)