如何使用Python在Windows上截取屏幕?

60

我正在创建一个Beta测试人员报告模块,以便他们可以发送对我的软件的评论,但我想在报告中包括一个截图选项。如何使用Python在Windows上对屏幕进行截图?我在Linux上找到了一些示例,但在Windows上没有太多运气。


1
这个方法对我有用:https://dev59.com/bm455IYBdhLWcg3wAvRI - User
9个回答

48

另一种非常快的方法是使用MSS模块。 它与其他解决方案不同之处在于它仅使用ctypes标准模块,因此不需要大型依赖项。 它是操作系统无关的,并且使用起来非常容易:

from mss import mss

with mss() as sct:
    sct.shot()

只需查找包含第一个监视器屏幕截图的screenshot.png文件。有许多可能的自定义选项,您可以使用ScreenShot对象和OpenCV / Numpy / PIL等进行操作。


2
请参见 https://python-mss.readthedocs.io/en/dev/examples.html,其中有更多的编程示例。 - tal
@Tiger-222:你怎么获取多个显示器? - Adrian Keister
2
@AdrianKeister: 好的链接是 https://python-mss.readthedocs.io/en/latest/examples.html;你会找到答案 :) - Tiger-222
@Tiger-222:非常棒!但有一个问题:用你的代码只截取了一个显示器,得到了一个很小的63kB文件。而在那个示例链接中,当我为三个屏幕截取单张截图时,得到了一个惊人的1.2 MB文件。有什么办法可以缩小完整屏幕截图的大小,以便与单个显示器进行比较? - Adrian Keister
1
没关系。我发现PNG文件的文件大小更多地取决于屏幕上显示的内容,而不是其他任何因素。再次感谢! - Adrian Keister
显示剩余2条评论

31

值得注意的是,ImageGrab 只在 MSWindows 上可用。

为了跨平台兼容性,最好使用 wxPython 库。 http://wiki.wxpython.org/WorkingWithImages#A_Flexible_Screen_Capture_App

import wx
app = wx.App()  # Need to create an App instance before doing anything
screen = wx.ScreenDC()
size = screen.GetSize()
bmp = wx.Bitmap(size[0], size[1])
mem = wx.MemoryDC(bmp)
mem.Blit(0, 0, size[0], size[1], screen, 0, 0)
del mem  # Release bitmap
bmp.SaveFile('screenshot.png', wx.BITMAP_TYPE_PNG)

属性错误:'module'对象没有属性'App'。 - tommy.carstensen
6
app = wx.App(),否则可能会出现错误:wx._core.PyNoAppError:必须先创建wx.App对象!同时,从这里下载wxPython:http://wxpython.org/download.php由于某种原因,如果只是使用“pip install wx”,那么它不是同一个“wx”库。 - cSn
CLI窗口出现空白。 - olekb
2
@Sepero:你要怎样获取多个显示器? - Adrian Keister
1
@ChristianAdam:你必须使用pip install -U wxPython进行安装。 - V15I0N
显示剩余2条评论

21

这可以通过PIL实现。首先,安装它,然后你可以像这样进行全屏截图:

import PIL.ImageGrab

im = PIL.ImageGrab.grab()
im.show()

2
PIL.ImageGrab仅适用于Windows和OS X操作系统。在Linux中,ImageGrab的替代方案是pyscreenshot。 - GNUton
1
从PIL 7.1.0开始,已在Linux上新增了对ImageGrab.grab()的支持 - Brent Vollebregt

14

你可以使用ImageGrab模块。ImageGrab适用于Windows和macOS,您需要PIL(Pillow)来使用它。这里是一个简单的例子:

from PIL import ImageGrab
snapshot = ImageGrab.grab()
save_path = "C:\\Users\\YourUser\\Desktop\\MySnapshot.jpg"
snapshot.save(save_path)

11

对于使用pyautogui的用户:

import pyautogui
screenshot = pyautogui.screenshot()

我该如何将图像写入PGN文件? - Yan Khonski
7
使用pyautogui.screenshot('filename.png')可以对屏幕进行截图并将其保存为指定的文件名。 - Al Sweigart
PIL库处理图像的结果比上述模块更好: from PIL import ImageGrab snapshot = ImageGrab.grab() save_path = r"E:\havaee\mypic.jpg" snapshot.save(save_path) - ali reza

5
一个简单的截图方法是通过Pygame实现的。
 pygame.image.save(Surface, filename)

'Surface'是您要截取屏幕的表面,而'filename'是保存图像的文件路径、名称和类型。

您可以导出为BMP、TGA、PNG或JPEG格式。截至Pygame 1.8版本,PNG和JPEG也能够使用。

如果未指定文件扩展名,它将默认为.TGA文件。

您甚至可以使用“os”库来保存到特定的文件目录。

例如:

import os
import pygame
surface = pygame.display.set_mode((100, 100), 0, 32)
surface.fill((255, 255, 255))
pygame.draw.circle(surface, (0, 0, 0), (10, 10), 15, 0)
pygame.display.update()
pygame.image.save(surface, os.path.expanduser("~/Desktop/pic.png"))

这将把“表面”上的任何内容保存为用户桌面上的pic.png


两个问题:1. Pygame是否跨平台?2. 是否可以获取多屏幕截图? - Adrian Keister
2
据我所知,Pygame是跨平台的。这段代码只会截取Pygame屏幕,而且仅限于Pygame屏幕。如果你的屏幕跨越了两个显示器,我认为它应该可以(尽管我无法测试)。希望这能帮到你! - CPSuperstore

3
import pyautogui

s = pyautogui.screenshot()
s.save(r'C:\\Users\\NAME\\Pictures\\s.png')

我宁愿使用 MSS,这个程序通过运行终端命令并将整个屏幕保存为 PNG 文件来工作。 - Barney Szabolcs
1
在Win10上为我工作。 - Radim Cernej

1
如果您想捕获特定正在运行的Windows应用程序,您需要通过循环遍历系统中所有打开的窗口来获取句柄。
如果您可以从Python脚本打开此应用程序,则更容易。然后,您可以将进程pid转换为窗口句柄。
另一个挑战是捕获在特定监视器中运行的应用程序。我有3个监视器系统,我必须找出如何捕获显示器2和3。
此示例将拍摄多个应用程序快照并将它们保存为JPEG文件。
import wx

print(wx.version())
app=wx.App()  # Need to create an App instance before doing anything
dc=wx.Display.GetCount()
print(dc)
#e(0)
displays = (wx.Display(i) for i in range(wx.Display.GetCount()))
sizes = [display.GetGeometry().GetSize() for display in displays]

for (i,s) in enumerate(sizes):
    print("Monitor{} size is {}".format(i,s))   
screen = wx.ScreenDC()
#pprint(dir(screen))
size = screen.GetSize()

print("Width = {}".format(size[0]))
print("Heigh = {}".format(size[1]))

width=size[0]
height=size[1]
x,y,w,h =putty_rect

bmp = wx.Bitmap(w,h)
mem = wx.MemoryDC(bmp)

for i in range(98):
    if 1:
        #1-st display:

        #pprint(putty_rect)
        #e(0)

        mem.Blit(-x,-y,w+x,h+y, screen, 0,0)

    if 0:
        #2-nd display:
        mem.Blit(0, 0, x,y, screen, width,0)
    #e(0)

    if 0:
        #3-rd display:
        mem.Blit(0, 0, width, height, screen, width*2,0)

    bmp.SaveFile(os.path.join(home,"image_%s.jpg" % i), wx.BITMAP_TYPE_JPEG)    
    print (i)
    sleep(0.2)
del mem

细节在这里


0

首先,使用pip3安装PrtSc库。

 import PrtSc.PrtSc as Screen
 screenshot=PrtSc.PrtSc(True,'filename.png')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接