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

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

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

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

好处是

  • 灵活
  • 速度快

缺点是:

  • 写法繁琐
  • 不跨平台
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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模块

1
2
3
4
5
6
7
8
9
10
11
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 官网

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from selenium import webdriver
import time
def capture(url, filename="capture.png"):
  browser = webdriver.Chrome(r"C:\Users\weidiao\Desktop\chromedriver_win32\chromedriver.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("//www.jb51.net")

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

ps:下面看下python基础===python实现截图

 
1
2
3

python实现全屏截图:

from PIL import ImageGrab
im = ImageGrab.grab() #可以添加一个坐标元组进去
im.save('F:\\12.png')

Python实现屏幕截图的两种方式的更多相关文章

  1. day2 编程语言介绍、Python运行程序的两种方式、变量

    一 编程语言介绍 1. 机器语言 用计算机能理解的二进制指令直接编写程序,直接控制硬件 2. 汇编语言 用英文标签取代二进制指令编写程序,本质也是直接控制硬件 3. 高级语言 用人能理解的表达方式去编 ...

  2. Python 输出百分比的两种方式

    Python 输出百分比的两种方式 注: 在python3环境下测试. 方式1:直接使用参数格式化:{:.2%} {:.2%}: 显示小数点后2位 显示小数点后2位: >>> pri ...

  3. Python 发送 email 的两种方式

    Python发送email的两种方式,分别为使用登录邮件服务器.调用sendmail命令来发送三种方法 Python发送email比较简单,可以通过登录邮件服务来发送,linux下也可以使用调用sen ...

  4. 【Python】Python figure显示的两种方式

    1. 两种方式: 终端输出图像新窗口输出图像 2. 终端输出命令: %matplotlib inline 新窗口输出命令: %matplotlib qt5 注意此两个语句是命令行输入,若在spyder ...

  5. Python 实现抽象类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现抽象类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

  6. python 字符编码的两种方式写法:# coding=utf-8和# -*- coding:utf-8 -*-

    python运行文件是总会出现乱码问题,为了解决这个问题,在文件开头加上: # coding=utf-8 或者 # -*- coding:utf-8  -*- # coding=<encodin ...

  7. python 配置文件返回的两种方式,写法不一样而已

    配置文件如下: [MODE]mode:{ "register":"all"} 或者 mode = {"register":"all ...

  8. python导入模块的两种方式

    第一种 from support import * 这种方式导入后可以直接调用(有命名冲突问题)命名冲突后定义的覆盖前定义的 如果在函数导入前定义 则导入函数覆盖 否则相反 if __name__ = ...

  9. python创建进程的两种方式

    1.方式1 import time import multiprocessing def task(arg): time.sleep(2) print(arg) def run(): # 进程1 p1 ...

随机推荐

  1. SQLServer中的cross apply和FOR XML PATH

    参考: FOR XML PATH:http://www.cnblogs.com/doubleliang/archive/2011/07/06/2098775.html cross apply:http ...

  2. Android开发艺术探索学习笔记(十)

    第十章  Android的消息机制 面试中经常会被问到的一个问题:handler是如何在子线程和主线程中进行消息的传递的,这个问题通过了解Android的消息机制可以得到一个准确的答案. Androi ...

  3. ListView中的TextView实现跑马灯效果

    1.TextView首先添加android:ellipsize="marquee"   android:marqueeRepeatLimit="marquee_forev ...

  4. CFileDialog类的详情

    CFileDialog类封装了Windows常用的文件对话框. 常用的文件对话框提供了一种简单的与Windows标准相一致的文件打开和文件存盘对话框功能. void CnotepadDlg::OnOp ...

  5. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十):接口服务整理

    通用操作 通用操作是指一般的增删改查操作,逻辑大体都是一致的,所以统一抽象到CURD接口,需要用到CURD的表直接实现接口就可以了. 通用操作主要有以下几个: 保存操作 /** * 保存操作 * @p ...

  6. Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装

    组件封装 为了避免组件代码的臃肿,这里对主要的功能部件进行封装,保证代码的模块化和简洁度. 组件结构 组件封装重构后,试图组件结构如下图所示 代码一览 Home组件被简化,包含导航.头部和主内容三个组 ...

  7. CentOS下SSH远程免密登录服务器

    .5服务器上配置,通过ssh远程免密登录192. 1.安装SSH,此处省略 2.生成公钥和私钥,生成的秘钥默认在/root/.ssh/文件夹里面 [root@localhost ~ ::&&a ...

  8. Redis注意事项

    1.Redis3.0没有虚拟内存概念,已从2.4就移除: 2.redis挂掉并重启时,如果有主从备份的,主机挂掉重启时先关掉主从备份,不然从机的数据会被冲洗掉 数据恢复时如果有 AOF(原理是将Rei ...

  9. tcp/ip通信中udp头部结构udphdrp->check校验计算

    通过raw socket修改通信数据后,可通过函数 set_udp_checksum1 重新校验计算iph->check值 在http://www.cnblogs.com/dpf-10/p/78 ...

  10. 【angular5项目积累总结】文件上传

    <div class="form-group row"> <label class="col-sm-2 col-form-label"> ...