步骤/目录:
无

本文首发于个人博客https://lisper517.top/index.php/archives/4257/,转载请注明出处。
本文的原文写作日期为2020年10月21日,主要目的是用Python截取屏幕。

最近需要对窗口截图,看到了以下文章:
https://www.cnblogs.com/Evan-fanfan/p/11097850.html

其中有些错误(乱写文章害人不浅啊)。经过我2天实验,大概搞清楚了3个关键api的用处。注释和代码如下:

# 根据句柄、截图位置和图片路径,对窗口的客户区截图并存到指定位置
# GetDC一类的需要用ReleaseDC释放,CreateDC一类的用DeleteDC释放,DeleteObject则删除一个逻辑笔、画笔、字体、位图、区域或者调色板,
def ClientRect_PrtSc(hwnd, area=None, filename=''):
    try:
        hwnd = hwnd
        if filename == '':
            filename = 'C:\\Users\\tadio\\Desktop\\helper\\pics\\targets\\{}.bmp'.format(
                hwnd)
        hwndDC = win32gui.GetDC(
            hwnd)  # 获取窗口的设备上下文Device Context。GetWindowDC包括了非客户区,而GetDC仅为客户区
        mfcDC = win32ui.CreateDCFromHandle(hwndDC)  # 获取mfcDC
        saveDC = mfcDC.CreateCompatibleDC()  # 创建可兼容DC
        saveBitMap = win32ui.CreateBitmap()  # 创建bitmap以保存图片
        '''MonitorDev = win32api.EnumDisplayMonitors(
            None, None)  # 获取显示器信息,枚举显示器,笔记本据说可能有问题'''
        x1, y1, x2, y2 = win32gui.GetClientRect(
            hwnd)  #GetClientRect获取客户区窗口位置,GetWindowRect获取整个窗口的位置信息
        x, y, w, h = (0, 0, 0, 0)
        if area == None:
            x = 0
            y = 0
            w = x2 - x1
            h = y2 - y1
        else:
            x, y, m, n = area
            w = m - x
            h = n - y
        saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)  # 为bitmap开辟空间
        # 对saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)的理解:
        # 1.mfc相当于一个虚拟屏幕。这里的参数w和h决定了这个屏幕的大小。
        # 2.屏幕的初始状态是黑色,每个坐标都是#000000
        # 3.之前有mfcDC = win32ui.CreateDCFromHandle(hwndDC),又有hwndDC = win32gui.GetDC(hwnd)
        #   mfcDC和hwnd窗口之间建立了某种关联,可以将hwnd窗口中的图像放到虚拟屏幕上
        saveDC.SelectObject(saveBitMap)  # 将截图保存到saveBitMap中
        saveDC.BitBlt((0, 0), (w, h), mfcDC, (x, y), win32con.SRCCOPY)
        # 对saveDC.BitBlt(坐标1, (w, h), mfcDC, 坐标2, win32con.SRCCOPY)的理解:
        # BitBlt的功能大概是把从hwnd窗口截到的图放到虚拟屏幕上,信息转入saveDC。
        # 1.坐标1是针对窗口截图的,指定截图放在黑色背景上的位置(指定左上角)
        # 2.w和h窗口截图的长宽,而坐标2指定了开始截图的位置
        #   这两个参数决定了从hwnd窗口的哪里截图、截多大的图
        # 3.mfcDC已经和hwnd窗口建立了关联,所以不需要指定虚拟屏幕从哪个窗口获得截图
        # 4.SRCCOPY意为将截图直接拷贝到虚拟屏幕中
        # 接下来的saveBitMap.SaveBitmapFile(saveDC, filename)则是对虚拟屏幕截图并保存到指定位置
        saveBitMap.SaveBitmapFile(saveDC, filename)
        # 清除数据
        win32gui.DeleteObject(saveBitMap.GetHandle())
        saveDC.DeleteDC()
        mfcDC.DeleteDC()
        win32gui.ReleaseDC(hwnd, hwndDC)
        info('对句柄 {} 标题 {} 的窗口截图并保存'.format(hwnd,
                                            win32gui.GetWindowText(hwnd)))
    except:
        error('客户区截图 出现错误')

标签: none

添加新评论