我如何在Wayland上获得纯Python的屏幕截图?



在最新的Pillow版本(9.1.0)中,grab()获取截图的功能只适用于X11,而不适用于Wayland。当我禁用Wayland时,它可以正常工作。

如何在Wayland上获得纯Python的屏幕截图?理想的解决方案不需要依赖其他库。

考虑到Wayland的安全模型,应用程序是否有可能获得完整的屏幕截图(包括其他应用程序的窗口)?使用scrot获取截图的结果是一个完全黑色的图像(类似于这里的问题)。然而,gnome-screenshot工作得很好,所以我知道这是可能的。

虽然有一个韦兰协议扩展wlr-screencopy-unstable-v1(通过直接与Wayland合成器交互),它不是一个实用的解决方案,因为许多合成器(例如GNOME/Mutter)不实现这个扩展。

一个更好的解决方案是使用XDG门户org.freedesktop.portal.Desktop服务通过dbus访问截图功能。

这也确保了应用程序在flatpak沙箱中运行。

最小的例子:

import dbus
from gi.repository import GLib
import dbus.mainloop.glib

def response_handler(response, result):
if response == 0:
print(f'Screenshot file: {result.get("uri")}')
else:
print("Failed to get screenshot")

def main():
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
my_name = bus.get_connection().get_unique_name()[1:].replace(".", "_")
response_path = f"/org/freedesktop/portal/desktop/request/{my_name}/my_token"
bus.add_signal_receiver(
response_handler,
dbus_interface="org.freedesktop.portal.Request",
path=response_path,
)
desktop = bus.get_object("org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop")
desktop.Screenshot("Screenshot", {"handle_token": "my_token"}, dbus_interface="org.freedesktop.portal.Screenshot")
loop = GLib.MainLoop()
loop.run()

if __name__ == "__main__":
main()

从看起来,没有清晰的方法可以实现这一点,所以您可能必须尝试一些可能的途径。这基本上是我收集到的关于这个任务的所有信息的总结:

  1. 尝试使用pyscreenshot,因为他们声称Wayland支持。t
  2. 如果你看看这个线程,特别是@surajRathi的评论,你会发现他已经实现了一个类似于你在问题中链接的SO答案的解决方案,但是在Python中。这似乎是最接近问题陈述的解决方案。
  3. 这个关于枕头问题的评论也概述了没有标准方法的事实,所以你必须尝试任何有效的方法。

最新更新