Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有没有比PIL.ImageGrab.grab()更好的捕获屏幕的方法?_Python_Windows_Windows Xp_Python Imaging Library_Python 2.5 - Fatal编程技术网

Python 有没有比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 >>>

我正在用python制作一个屏幕截图程序。我当前的问题是PIL.ImageGrab.grab()提供与2秒后相同的输出。例如,我想我不太清楚,在下面的程序中,几乎所有的图像都是相同的,都有相同的Image.tostring()值,即使我在PIL.ImageGrab.grab循环执行期间移动了屏幕

>>> 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()