[英]Is there any better way to capture the screen than PIL.ImageGrab.grab()?
I am making a screen capture program with python. 我正在用python制作一个截屏程序。 My current problem is PIL.ImageGrab.grab() gives me the same output as 2 seconds later.
我目前的问题是PIL.ImageGrab.grab()在2秒后给出了相同的输出。 For instance, for I think I am not being clear, in the following program, almost all the images are the same, have the same Image.tostring() value, even though I was moving my screen during the time the PIL.ImageGrab.grab loop was executing.
例如,因为我认为我不清楚,在下面的程序中,几乎所有图像都是相同的,具有相同的Image.tostring()值,即使我在PIL.ImageGrab期间移动我的屏幕。抓斗循环正在执行。
>>> 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
>>>
This is a problem, as all the images are the same but 1. 1 out of 30 is different. 这是一个问题,因为所有图像都是相同的,但是30个中的1个是不同的。 That would make for a absolutly horrable quality video.
这将成为一个绝对可怕的高质量视频。 Please, tell me if there is any better quality alternative to PIL.ImageGrab.grab().
请告诉我是否有更好的替代品PIL.ImageGrab.grab()。 I need to capture the whole screen.
我需要捕捉整个屏幕。 Thanks!
谢谢!
EDIT: 编辑:
So far, it looks like the best alternative is to use pywin32. 到目前为止,看起来最好的选择是使用pywin32。 I am using that for now, but it is very slow.
我现在正在使用它,但它很慢。 I don't really care about compatability, as for now this project is personal.
我并不真正关心兼容性,因为现在这个项目是个人的。 Every time I work out the frame rate of the program, pywin32 is so slow, it's in the negatives.
每次我计算出程序的帧速率时,pywin32都是如此之慢,它是负面的。 Please tell me if there is a faster alternative.
请告诉我是否有更快的替代方案。 Thanks!
谢谢!
There are many alternatives to PIL.ImageGrab. PIL.ImageGrab有很多替代品。
If you want cross-platform, nearly every major windowing library has screen grab capabilities. 如果您想要跨平台,几乎每个主要的窗口库都有屏幕抓取功能。 Here's an example using PyQt4 :
这是使用PyQt4的示例:
import sys
from PyQt4.QtGui import QPixmap, QApplication
app = QApplication(sys.argv)
QPixmap.grabWindow(QApplication.desktop().winId()).save('screenshot.jpg', 'jpg')
If you want something different from the default settings for what Qt considers "the desktop", you'll need to dig into the PyQt or Qt documentation. 如果您想要与Qt认为“桌面”的默认设置不同的东西,您需要深入了解PyQt或Qt文档。
The downside is that these cross-platform windowing libraries are usually pretty heavy duty in terms of installation, distribution, and even sometimes how you structure your program. 缺点是这些跨平台窗口库在安装,分发方面通常都很重要,有时甚至是你如何构建程序。
The alternative is to use Windows-specific code. 另一种方法是使用特定于Windows的代码。 While it's possible to ctypes your way directly to the Windows APIs, a much simpler solution is PyWin32 .
虽然可以直接使用Windows API,但更简单的解决方案是PyWin32 。
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')
As usual with Win32, you have to specify exactly what you mean by "the desktop"; 像往常一样,你必须准确指出“桌面”的含义; this version specifies the "virtual screen" for the current session, which is the combination of all of the monitors if you're running locally at the console, or the remote view if you're running over Terminal Services.
此版本指定当前会话的“虚拟屏幕”,如果您在控制台本地运行,则为所有监视器的组合,如果您在终端服务上运行,则为远程视图。 If you want something different, you'll have to read the relevant Win32 documentation at MSDN.
如果您想要不同的东西,您必须阅读MSDN上的相关Win32文档。 But for the most part, translating from that documentation to PyWin32 is trivial.
但在大多数情况下,从文档转换到PyWin32是微不足道的。
(By the way, even though I say "Win32", the same all works for Win64.) (顺便说一句,即使我说“Win32”,同样适用于Win64。)
A modern cross-platform solution is to use Python MSS . 现代的跨平台解决方案是使用Python MSS 。
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()
On my slow laptop this function can return screenshots at up to 27 fps. 在我的慢速笔记本电脑上,此功能可以返回最高27 fps的屏幕截图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.