【问题标题】:How can I close an image shown to the user with the Python Imaging Library?如何使用 Python 图像库关闭向用户显示的图像?
【发布时间】:2011-07-17 16:08:32
【问题描述】:

我有几张图片想用 Python 向用户展示。用户应该输入一些描述,然后应该显示下一个图像。

这是我的代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os, glob
from PIL import Image

path = '/home/moose/my/path/'
for infile in glob.glob( os.path.join(path, '*.png') ):
    im = Image.open(infile)
    im.show()
    value = raw_input("Description: ")
    # store and do some other stuff. Now the image-window should get closed

它正在工作,但用户必须自己关闭图像。输入描述后我可以让python关闭图像吗?

我不需要 PIL。如果您对另一个库/bash 程序(带有子进程)有其他想法,也可以。

【问题讨论】:

    标签: python python-imaging-library


    【解决方案1】:

    psutil 可以获取im.show() 创建的display 进程的 pid,并在每个操作系统上用该 pid 杀死该进程:

    import time
    
    import psutil
    from PIL import Image
    
    # open and show image
    im = Image.open('myImageFile.jpg')
    im.show()
    
    # display image for 10 seconds
    time.sleep(10)
    
    # hide image
    for proc in psutil.process_iter():
        if proc.name() == "display":
            proc.kill()
    

    【讨论】:

    • @IDelgado psutil 应该可以在 OS X 下工作。请在项目的issue tracker 上描述您的问题。
    • @Bengt 在proc.name 之后使用一个方法,因此您可以像proc.name() 一样调用它,然后才会起作用。请修复它,然后您就可以投票了。
    • @IDelgado 见上一条评论。
    • @GyörgySolymosi @IDelgado 是的,在较新版本的 psutil 中,proc.name 是一种方法而不是字符串属性。如果检查 name 属性,脚本将无效退出,因为它们看起来像这样:<bound method Process.name of <psutil.Process(pid=14358,name='display') at 19774288>> 感谢您指出这一点,我更新了我的答案。希望以后没有人会绊倒它。
    • 在 macOS 中,proc.name() 将是“预览”。
    【解决方案2】:

    我之前修改了this recipe,以便在 Python 中进行一些图像处理。它使用Tkinter,因此不需要PIL以外的任何模块。

    '''This will simply go through each file in the current directory and
    try to display it. If the file is not an image then it will be skipped.
    Click on the image display window to go to the next image.
    
    Noah Spurrier 2007'''
    import os, sys
    import Tkinter
    import Image, ImageTk
    
    def button_click_exit_mainloop (event):
        event.widget.quit() # this will cause mainloop to unblock.
    
    root = Tkinter.Tk()
    root.bind("<Button>", button_click_exit_mainloop)
    root.geometry('+%d+%d' % (100,100))
    dirlist = os.listdir('.')
    old_label_image = None
    for f in dirlist:
        try:
            image1 = Image.open(f)
            root.geometry('%dx%d' % (image1.size[0],image1.size[1]))
            tkpi = ImageTk.PhotoImage(image1)
            label_image = Tkinter.Label(root, image=tkpi)
            label_image.place(x=0,y=0,width=image1.size[0],height=image1.size[1])
            root.title(f)
            if old_label_image is not None:
                old_label_image.destroy()
            old_label_image = label_image
            root.mainloop() # wait until user clicks the window
        except Exception, e:
            # This is used to skip anything not an image.
            # Warning, this will hide other errors as well.
            pass
    

    【讨论】:

    • 它需要 ImageTK。但我刚刚找到了合适的 Ubuntu 软件包:sudo apt-get install python-imaging-tk。我是否遗漏了什么,或者用户无法提供输入?我想关闭当前窗口并打开下一个窗口(或者只是在当前窗口中打开下一个窗口),而不需要任何其他用户交互,而不是编写描述(以 enter 结束)。
    • ImageTK 应该带有 PIL... 如果您愿意,您可以修改窗口并添加文本字段和按钮。我的Tkinter很老了,一般我用wx
    【解决方案3】:

    show 方法“主要用于调试目的”并生成一个您无法获得句柄的外部进程,因此您无法以适当的方式杀死它。

    对于 PIL,您可能希望使用其 GUI 模块之一,例如 ImageTkImageQtImageWin

    否则,只需使用 subprocess 模块从 Python 手动生成图像查看器:

    for infile in glob.glob( os.path.join(path, '*.png')):
        viewer = subprocess.Popen(['some_viewer', infile])
        viewer.terminate()
        viewer.kill()  # make sure the viewer is gone; not needed on Windows
    

    【讨论】:

    • 嗨 larsmans,这正是我所寻找的。您能否将 Popen 的输入添加到列表中(添加 [])?没有它,它就行不通。也感谢您提到 ImageTk 和 ImageQt,我会看看它们。
    • @moose:是的,忘了[],抱歉。
    • 我如何在 OSX 上以some_viewer 使用预览?
    • 文档链接已损坏
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 2014-09-12
    相关资源
    最近更新 更多