从零开始的明日方舟python脚本创作(四)截屏模块

脚本原理

重述下本脚本的原理:确定了几个固定的检测区域,进行截屏,然后再和已经保存下来的区域截图进行对比,确定相应的操作。所以这几个区域的位置是事先就已经确定好了的。如何获取这几个区域的位置?可以通过截取窗口的屏幕之后通过画图查看相应的像素位置。如下图:
从零开始的明日方舟python脚本创作(四)截屏模块_第1张图片
事先截取了一个完整的子窗口,然后根据画图软件就可以看到红点所在的像素位置为(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

逐一截取事先确定的子区域,返回图像对比模块两张图片比较的结果。默认所有子区域识别不一致就不需要操作。以上就是截屏模块的相应内容了,祝好!

你可能感兴趣的:(python,python)