2011-07-17 33 views
11

Tengo varias imágenes que me gustaría mostrar al usuario con Python. El usuario debe ingresar alguna descripción y luego se debe mostrar la siguiente imagen.¿Cómo puedo cerrar una imagen que se muestra al usuario con la Biblioteca de imágenes de Python?

Este es mi código:

#!/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 

Se está trabajando, pero el usuario tiene que cerrar la imagen de sí mismo. ¿Puedo hacer que Python cierre la imagen después de que se haya ingresado la descripción?

No necesito PIL. Si tiene otra idea con otra biblioteca/programa bash (con subproceso), también estará bien.

Respuesta

12

El método show "está destinado principalmente a la depuración" y genera un proceso externo para el que no se obtiene un identificador, por lo que no se puede eliminar de manera adecuada.

Con PIL, es posible que desee utilizar uno de sus módulos de GUI, como ImageTk, ImageQt o ImageWin.

De lo contrario, simplemente desovar manualmente un visor de imágenes de Python con el módulo subprocess:

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 
+0

Hola larsmans, eso es exactamente lo que he buscado. ¿Podría por favor hacer la entrada de Popen a una lista (agregando [])? Sin eso, no funciona. Gracias también por mencionar ImageTk e ImageQt. Los echaré un vistazo. –

+0

@moose: sí, se olvidó de '[]', lo siento. –

+1

¿cómo usaría la vista previa en OSX como 'some_viewer'? –

3

He modificado this recipe antes de hacer algún trabajo de imagen en Python. Utiliza Tkinter, por lo que no requiere ningún módulo además de 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 
+0

Requiere ImageTK. Pero acabo de encontrar el paquete adecuado de Ubuntu: sudo apt-get install python-image-tk. ¿Me estoy perdiendo algo o no es posible que el usuario haga una aportación? Quería cerrar la ventana actual y abrir la siguiente (o simplemente abrir la siguiente en la ventana actual) sin ninguna otra interacción del usuario que escribir una descripción (finalizando con enter). –

+0

ImageTK debe venir con PIL ... Puede modificar la ventana y marcar un campo de texto y un botón si lo desea. Mi 'Tkinter' es muy viejo, generalmente uso' wx'. –

7

psutil puede obtener el pid del proceso display creado por im.show() y matar el proceso con pid que en cada sistema operativo:

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

Esto no parece funcionar en mac osx –

+0

@IDelgado psutil debe funcionar bajo OS X. Describa su problema en el [rastreador de problemas] del proyecto (https://github.com/giampaolo/psutil/issues). – Bengt

+0

@Bengt Después de 'proc.name' un método para que pueda llamarlo como' proc.name() 'y solo entonces funcionará. Por favor, corrígelo y tú y tú obtendrás un voto positivo. – Geeocode

Cuestiones relacionadas