【问题标题】:Python detect x server error when showing imagePython在显示图像时检测x服务器错误
【发布时间】:2019-05-30 07:59:03
【问题描述】:

在 Python 中使用 Image.show() 时有什么方法可以捕获 X 服务器异常?

当我在没有使用-X-Y 选项的情况下尝试通过 ssh 连接显示图像时,我想停止运行程序,因为这将在循环中运行,所以没有意义正在尝试加载更多图像。
这将显示错误 display.im6: unable to open X server ' @ error/display.c/DisplayImageCommand/428.'
但似乎无法捕捉到这一点,因为我认为操作系统在执行 PIL Image.show() 调用后会显示此错误。

from PIL import Image
img = Image.open(img_name)
try:
    img.show()
except Exception as e:
    print(e)
    sys.exit()

调用永远不会进入 except 调用。

【问题讨论】:

    标签: python linux ssh python-imaging-library


    【解决方案1】:

    从 PIL 的代码 https://pillow.readthedocs.io/en/5.3.x/_modules/PIL/ImageShow.html 可以看出,图像中的 show 方法最终将使用启发式确定的命令调用 os.system 来显示图像。从这里可以看出,问题在于,os.system 调用的返回值被忽略了,因此,即使图像不显示,程序也永远不会知道。

    如果原始 os.system 返回的不是零,您可以尝试猴子修补 os.system 来引发错误,然后您就会遇到异常。 但是,在尝试这种方式时,我注意到对于我的默认查看器,它无论如何都会返回“0”作为退出代码,即使显示损坏,所以它不能被“系统”检测到。您必须使用能够正确调用subprocess.Popen 的函数来对os.system 进行monkeypatch,并且不仅要检查退出代码,还要检查被调用命令的sdterr - 它开始变得棘手了。

    因此,第二个更简单且可能更安全的方法是让您的程序检查DISPLAY 环境变量的内容。如果它为空或无效,任何使用 X 显示的尝试都将失败:

    import os
    
    if not os.environ.get("DISPLAY"):
        raise RuntimeError("Display is not properly set. Aborting!")
    

    为什么会这样?从历史上看,PIL(最初的 PIL,而不是当前维护的 Pillow)show 代码是对 xv 的简单硬编码调用 - 它可能被发现是仅对原始库所有者的调试有用。尽管今天它更加复杂,但在几个(仍然是硬编码的)选项中寻找合适的外部查看器,无论如何都不是“一流的 UI”。我认为它适合您描述的用例,但除此之外,也许第一个选择是移动到matplotlib 以在 UI 中显示图像,该 UI 可以更好地由 Python 代码控制,而无需求助使用 Qt 或 Tkinter 编写完整的 GUI 代码。

    【讨论】:

    • 太好了,和我想的一样,谢谢你的尝试!另外,您的代码应该是if "DISPLAY" not in os.environ:,因为如果您尝试直接访问它会出现 KeyError
    • 感谢您在最后添加解释。另一种选择是使用 OpenCV 的图像显示功能
    猜你喜欢
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 2013-03-06
    • 1970-01-01
    • 2014-01-16
    相关资源
    最近更新 更多