Python 有没有比PIL.ImageGrab.grab()更好的捕获屏幕的方法?
我正在用python制作一个屏幕截图程序。我当前的问题是PIL.ImageGrab.grab()提供与2秒后相同的输出。例如,我想我不太清楚,在下面的程序中,几乎所有的图像都是相同的,都有相同的Image.tostring()值,即使我在PIL.ImageGrab.grab循环执行期间移动了屏幕Python 有没有比PIL.ImageGrab.grab()更好的捕获屏幕的方法?,python,windows,windows-xp,python-imaging-library,python-2.5,Python,Windows,Windows Xp,Python Imaging Library,Python 2.5,我正在用python制作一个屏幕截图程序。我当前的问题是PIL.ImageGrab.grab()提供与2秒后相同的输出。例如,我想我不太清楚,在下面的程序中,几乎所有的图像都是相同的,都有相同的Image.tostring()值,即使我在PIL.ImageGrab.grab循环执行期间移动了屏幕 >>> from PIL.ImageGrab import grab >>> l = [] >>> import time >>>
>>> from PIL.ImageGrab import grab
>>> l = []
>>> import time
>>> for a in l:
l.append(grab())
time.sleep(0.01)
>>> for a in range(0, 30):
l.append(grab())
time.sleep(0.01)
>>> b = []
>>> for a in l:
b.append(a.tostring())
>>> len(b)
30
>>> del l
>>> last = []
>>> a = 0
>>> a = -1
>>> last = ""
>>> same = -1
>>> for pic in b:
if b == last:
same = same + 1
last = b
>>> same
28
>>>
这是一个问题,因为所有图像都是相同的,只有1个。三十分之一是不同的。这将是一个绝对令人难以忍受的高质量视频。请告诉我是否有比PIL.ImageGrab.grab()更高质量的替代品。我需要捕捉整个屏幕。谢谢
编辑:
到目前为止,最好的选择似乎是使用pywin32。我现在正在使用它,但是速度很慢。我真的不关心兼容性,因为现在这个项目是个人的。每次我计算程序的帧速率时,pywin32都非常慢,都是负片。请告诉我是否有更快的选择。谢谢 PIL.ImageGrab有很多替代品 如果您想要跨平台,几乎每个主要的窗口库都有屏幕抓取功能。下面是一个示例,使用: 如果您想要不同于Qt所认为的“桌面”的默认设置,则需要深入研究PyQt或Qt文档 缺点是,这些跨平台窗口库通常在安装、分发,甚至有时在程序的结构方面都非常繁重 另一种方法是使用特定于Windows的代码。虽然可以直接将您的方式键入Windows API,但一个更简单的解决方案是 与Win32一样,您必须准确地指定“桌面”的含义;此版本指定当前会话的“虚拟屏幕”,如果在控制台本地运行,则为所有监视器的组合;如果在终端服务上运行,则为远程视图。如果您想要一些不同的东西,您必须阅读MSDN上的相关Win32文档。但在大多数情况下,从该文档到PyWin32的转换是微不足道的
(顺便说一句,尽管我说的是“Win32”,但所有这些都适用于Win64。)一个现代的跨平台解决方案就是使用
在我的慢速笔记本电脑上,此功能可以以每秒27帧的速度返回屏幕截图。如果您使用的是X Windows,则其插件可能是一个很好的解决方案。30*0.01=0.3秒。您确定在这段时间内移动了windows吗?您想要跨平台的东西,还是特定于windows的东西可以?您可以使用重载框架(如Qt或wx)吗?
pywin32
的哪个部分“非常慢”?一般来说,与wx、Qt或其他任何东西相比,它在本机Windows API上的包装要薄得多。我最后做了最后一个,除了wx模块。后一种方法速度稍快,但它生成的文件要重得多(对于1366x786分辨率的图像,约5mb),并且它仅限于.bmp
图像,与第一种方法不同。@MadeOfAir:如果您已经在使用PIL,您可以在保存之前轻松地将bmp
转换为png
或任何您想要的格式。(之所以是5MB,是因为bmp
文件是未压缩的。)我相信也有更高级的Win32 API方法可以从位图对象创建PNG文件,但你必须自己扫描MSDN或谷歌才能找到它们。这救了我。。应该是最受欢迎的(尤其是那些不能使用win32的mac用户)@jchaykow的win32 api比mss快吗?@csch0我读过其他人把win32降到了16ms,大约是60fps,所以如果这是真的,我认为它稍微快一点。但对于我的使用,我不需要任何超过20fps的速度,mss比这快得多。我在我的i5-4440@3.10GHz上进行了测试,性能与枕头上的完全相同
import sys
from PyQt4.QtGui import QPixmap, QApplication
app = QApplication(sys.argv)
QPixmap.grabWindow(QApplication.desktop().winId()).save('screenshot.jpg', 'jpg')
import win32gui, win32ui, win32con, win32api
hwin = win32gui.GetDesktopWindow()
width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
hwindc = win32gui.GetWindowDC(hwin)
srcdc = win32ui.CreateDCFromHandle(hwindc)
memdc = srcdc.CreateCompatibleDC()
bmp = win32ui.CreateBitmap()
bmp.CreateCompatibleBitmap(srcdc, width, height)
memdc.SelectObject(bmp)
memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY)
bmp.SaveBitmapFile(memdc, 'screenshot.bmp')
from mss import mss
from PIL import Image
def capture_screenshot():
# Capture entire screen
with mss() as sct:
monitor = sct.monitors[1]
sct_img = sct.grab(monitor)
# Convert to PIL/Pillow Image
return Image.frombytes('RGB', sct_img.size, sct_img.bgra, 'raw', 'BGRX')
img = capture_screenshot()
img.show()