9

I would like to display an image with Python and close it after user enters the name of the image in terminal. I use PIL to display image, here is the code:

im = Image.open("image.jpg")
im.show()

My application display this image, but user task is to recognize object on image and write answer in terminal. If answer entered is correct user should get another image. Problem with PIL is that I can't close the image and with research the only solution was to kill the process of image viewer, but this is not really reliable and elegant. Are there any other libraries for displaying images that have methods like .show() and .close() ?

NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
gorgi93
  • 2,457
  • 8
  • 30
  • 53

5 Answers5

4

Just open any image viewer/editor in a separate process and kill it once user has answered your question e.g.

from PIL import Image
import subprocess

p = subprocess.Popen(["display", "/tmp/test.png"])
raw_input("Give a name for image:")
p.kill()
Anurag Uniyal
  • 85,954
  • 40
  • 175
  • 219
  • 3
    Does this rely on "display" being an executable that displays an image, on the user's path? That seems a bit... fragile? – GreenAsJade Jun 25 '14 at 07:32
  • That is an example, but software has to rely on something to work, this is the easiest way for a given situation, in general for cross platform app you might use some library like wxPython or PyQT to create a window and display image. You can also use PIL's `im.show` which may be cross platform but you can't close the window automatically. – Anurag Uniyal Jun 26 '14 at 22:26
4

A little late to the party, but (as a disgruntled data scientist who really can't be bothered to learn gui programming for the sake of displaying an image) I can probably speak for several other folks who would like to see an easier solution for this. I figured out a little work around by expanding Anurag's solution:

Make a second python script (let's call it 'imviewer.py'):

from skimage.viewer import ImageViewer
from skimage.io import imread

img = imread('image.png') #path to IMG
view = ImageViewer(img)
view.show()

Then in your main script do as Anurag suggested:

import subprocess
p = subprocess.Popen('python imviewer.py')
#your code
p.kill()

You can make the main script save the image you want to open with 'imviewer.py' temporarily, then overwrite it with the next image etc.

Hope this helps someone with this issue!

Tristan HB
  • 125
  • 2
  • 8
  • Which packages need to be installed to use these scripts? I can't find any exact matches and your answer does not include the install information. – Anthony May 09 '20 at 20:10
  • The skimage package full title is scikit-image. The subprocess module is part of the standard python library and should not need installing separately. – Tristan HB May 10 '20 at 23:11
2

Terminal is meant to deal with linear command flow - meaning it asks a question, user answers, and then it can ask a different question. What you are trying to do here is for terminal to do two things, show an image and at the same time ask user a question. To do this you can do two of either things:

Multiprocessing

You can start a new thread/process and make PIL show the image using that thread, and meanwhile in the first thread/process ask a user a question. Then after the user answers, you can close the other thread/process. You can take a look at Python's threading module (link) for more information on how you can do that.

GUI

Instead of making your user interface in terminal, make a simple GUI application using whatever framework you are comfortable. I personally like PyQt4. Qt is very powerful GUI development toolkit and PyQt4 is a wrapper for it. If you make a GUI, then what you are tyring to do is rather trivial.

miki725
  • 27,207
  • 17
  • 105
  • 121
2

Not all GUIs are difficult to use.

Here is a single-line solution using PySimpleGUI. Normally I wouldn't write it as a single line, but since it's a one-off, perhaps doesn't need adding to, then it's OK to do.

import PySimpleGUI as sg

sg.Window('My window').Layout([[ sg.Image('PySimpleGUI.png') ]]).Read()

enter image description here

Mike from PSG
  • 5,312
  • 21
  • 39
1

Might be an overkill, but for me the easiest and most robust solution was just to use matplotlib as it properly keeps track of the figures it creates, e.g. :

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

imgplot = plt.imshow(mpimg.imread('animal.png'))
plt.ion()
plt.show()
animal_name = raw_input("What is the name?: ")
plt.close()
  • Tried on Jupyter notebook, and image doesn't seem to close. With Python idle, the picture didn't close as well. When I manually tried closing it after running it with IDLE, it just froze and crashed. – Moondra May 02 '17 at 17:14
  • I have tried it with just normal python 2 & 3 on both Ubuntu and Mac OS and it worked fine - I don't know about the specifics with frameworks such as Jupyter. – Maximilian Schulz May 03 '17 at 09:53