• Python实现屏幕截图的两种方式


    Python实现屏幕截图有两种方式:

    • 使用windows API
    • 使用PIL中的ImageGrab模块

    下面对两者的特点和用法进行详细解释。

    一、Python调用windows API实现屏幕截图

    好处是

    • 灵活
    • 速度快

    缺点是:

    • 写法繁琐
    • 不跨平台
    import time
    import win32gui, win32ui, win32con, win32api
    
    
    def window_capture(filename):
        hwnd = 0  # 窗口的编号,0号表示当前活跃窗口
        # 根据窗口句柄获取窗口的设备上下文DC(Divice Context)
        hwndDC = win32gui.GetWindowDC(hwnd)
        # 根据窗口的DC获取mfcDC
        mfcDC = win32ui.CreateDCFromHandle(hwndDC)
        # mfcDC创建可兼容的DC
        saveDC = mfcDC.CreateCompatibleDC()
        # 创建bigmap准备保存图片
        saveBitMap = win32ui.CreateBitmap()
        # 获取监控器信息
        MoniterDev = win32api.EnumDisplayMonitors(None, None)
        w = MoniterDev[0][2][2]
        h = MoniterDev[0][2][3]
        # print w,h   #图片大小
        # 为bitmap开辟空间
        saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
        # 高度saveDC,将截图保存到saveBitmap中
        saveDC.SelectObject(saveBitMap)
        # 截取从左上角(0,0)长宽为(w,h)的图片
        saveDC.BitBlt((0, 0), (w, h), mfcDC, (0, 0), win32con.SRCCOPY)
        saveBitMap.SaveBitmapFile(saveDC, filename)
    
    
    beg = time.time()
    for i in range(10):
        window_capture("haha.jpg")
    end = time.time()
    print(end - beg)
    
    

    输出结果为0.375秒,也就是说通过windows API每次截图只需要0.0375s,真是快得一逼呀。

    二、使用PIL的ImageGrab模块

    import time
    
    import numpy as np
    from PIL import ImageGrab
    
    # 每抓取一次屏幕需要的时间约为1s,如果图像尺寸小一些效率就会高一些
    beg = time.time()
    debug = False
    for i in range(10):
        img = ImageGrab.grab(bbox=(250, 161, 1141, 610))
        img = np.array(img.getdata(), np.uint8).reshape(img.size[1], img.size[0], 3)
    end = time.time()
    print(end - beg)
    

    输出结果为4.015秒,也就是说截取一次屏幕需要半秒钟,更何况此处只截取了窗口的一部分矩形区域。所以ImageGrab模块能用是能用,就是有点慢。

    三、使用Selenium截图

    使用Selenium只能进行WEB程序截图
    使用Selenium的各个浏览器需要制定驱动的位置,驱动下载地址参见Selenium 官网

    from selenium import webdriver
    import time
    
    
    def capture(url, filename="capture.png"):
        browser = webdriver.Chrome(r"C:UsersweidiaoDesktopchromedriver_win32chromedriver.exe")
        browser.set_window_size(1200, 900)
        browser.get(url)  # Load page
        browser.execute_script("""
        (function () {
          var y = 0;
          var step = 100;
          window.scroll(0, 0);
    
          function f() {
            if (y < document.body.scrollHeight) {
              y += step;
              window.scroll(0, y);
              setTimeout(f, 50);
            } else {
              window.scroll(0, 0);
              document.title += "scroll-done";
            }
          }
    
          setTimeout(f, 1000);
        })();
      """)
    
        for i in range(30):
            if "scroll-done" in browser.title:
                break
            time.sleep(1)
        beg = time.time()
        for i in range(10):
            browser.save_screenshot(filename)
        end = time.time()
        print(end - beg)
        browser.close()
    
    
    capture("http://www.cnblogs.com/weidiao")
    
    

    打印时间为3.033s,速度介于windows API和PIL ImageGrab模块之间。

  • 相关阅读:
    ASP.NET事件顺序
    Discuz!NT 代码阅读笔记(9)DNT数据库中唯一的用户函数解析
    Discuz!NT代码阅读笔记(2)网站安装自动化论坛程序安装及初始化过程
    ASP.NET网站和ASP.NET应用程序的区别
    根据日期获得当天是星期几/蔡勒(Zeller)公式
    Discuz!NT 代码阅读笔记(8)DNT的几个分页存储过程解析
    Excel导出数据报表的类
    MSDN Magazine的下载
    openSuSE 11.0正式版发布了
    用lighttpd+mono在Linux上面跑ASP.NET程序
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/8051280.html
Copyright © 2020-2023  润新知