重述下本脚本的原理:确定了几个固定的检测区域,进行截屏,然后再和已经保存下来的区域截图进行对比,确定相应的操作。所以这几个区域的位置是事先就已经确定好了的。如何获取这几个区域的位置?可以通过截取窗口的屏幕之后通过画图查看相应的像素位置。如下图:
事先截取了一个完整的子窗口,然后根据画图软件就可以看到红点所在的像素位置为(685,414)。如果需要检测开始行动这个按钮,那么就可以根据画图确定开始行动这个按钮所在的截屏区域,然后通过截屏模块截取相应的图片并保存下来。
import win32gui, win32ui, win32con#pywin32,第三方库
from PIL import Image#PIL,第三方库
import TesseractOcr#概述中提到的自己写的图像对比模块脚本
def startInit():
global cropInof#需要截屏的子区域
global wdname
global hWnd
global width
global height
global heightRatio,widthRatio
oriWidth=1024#截屏时的窗口分辨率
oriHright=576#截屏时的窗口分辨率
cropInof=[(851,442,890,480),(835,455,996,490),(830,296, 934,513),(36,470,310,540)]#需要截屏的区域
wdname = u'夜神模拟器'
hWnd = win32gui.FindWindow(0, wdname) # 获取窗口句柄
hWnd=win32gui.FindWindowEx(hWnd,0,None,'ScreenBoardClassWindow')
#获取句柄窗口的大小信息
left, top, right, bot = win32gui.GetWindowRect(hWnd)
width = right - left
height = bot - top
heightRatio=height/oriHright#窗口高度的缩放比值
widthRatio=width/oriWidth#窗口宽度的缩放比值
#屏幕适配截屏区域也随之改变
for item in cropInof:
left, top, right, bot =item
left=math.floor(left*widthRatio)
right=math.floor(right*widthRatio)
top=math.floor(top*heightRatio)
bot=math.floor(bot*heightRatio)
cropInof[index]=(left,top,right,bot)
index+=1
获取窗口句柄的同时,确定了当前的窗口分辨率与制作对比截图截屏时的窗口分辨率的宽高比值,便于后续进行子区域的截屏区域做调整,也方便模拟器窗口大小可以不受约束。之后对需要截屏的子区域进行相应的缩放。
#返回句柄窗口的设备环境,覆盖整个窗口,包括非客户区,标题栏,菜单,边框
def ScreenShot():
hWndDC = win32gui.GetWindowDC(hWnd)
#创建设备描述表
mfcDC = win32ui.CreateDCFromHandle(hWndDC)
#创建内存设备描述表
saveDC = mfcDC.CreateCompatibleDC()
#创建位图对象准备保存图片
saveBitMap = win32ui.CreateBitmap()
#为bitmap开辟存储空间
saveBitMap.CreateCompatibleBitmap(mfcDC,width,height)
#将截图保存到saveBitMap中
saveDC.SelectObject(saveBitMap)
#保存bitmap到内存设备描述表
saveDC.BitBlt((0,0), (width,height), mfcDC, (0, 0), win32con.SRCCOPY)
###获取位图信息
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)
###生成图像
im_PIL = Image.frombuffer('RGB',(bmpinfo['bmWidth'],bmpinfo['bmHeight']),bmpstr,'raw','BGRX',0,1)
#内存释放
win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hWnd,hWndDC)
# im_PIL.show() #显示
#im_PIL = im_PIL.crop((20,20,40,40))
#im_PIL.save("im_PIL.png") #保存
return im_PIL
这段代码基本都是复制的CSDN上某位大佬写的,自己之前从来没有接触到这块的内容。根据代码搜索也没有看到原贴,所以就没贴原贴出处了。这里获取了一个窗口的完整截屏并返回。若需要查看截屏情况,可以直接调用show()接口展示图片。需要提前截取用来对比的图片,也是通过这里截取保存的。
def compareImage(image):
index=0
print("开始图像对比")
for info in cropInof:
cropImg=image.crop(info)
#cropImg.show()
flag=TesseractOcr.CompareImage(cropImg,index)
if(flag):
return index
index+=1
print("图像对比结束")
return -1
逐一截取事先确定的子区域,返回图像对比模块两张图片比较的结果。默认所有子区域识别不一致就不需要操作。以上就是截屏模块的相应内容了,祝好!