Python – Pillow ImageShow.show() isn't displaying images (Raspbian)

Question:

All I’m trying to do is display an image using Pillow on Raspberry Pi 3

First tried using this code:

from PIL import Image 
from PIL import ImageShow

imageA = Image.open('Moth.png')
ImageShow.show(imageA)
print("Done")

It didn’t work, no error code, no nothing, it just skipped the code entirely

I digged a bit around and found out that maybe there could be an issue with the image displayer, so I tried adding it in like this:

from PIL import Image 
from PIL import ImageShow

imageA = Image.open('Moth.png')
ImageShow.show(imageA,title=None,command='GPicView')
print("Done")

It didn’t work either, I also tried installing fim and using

ImageShow.show(imageA,title=None,command='fim')

like one of the answers on this site suggested, but that didn’t work either

I made sure that fim has been installed correctly, so there must be something wrong with the code, but I can’t understand what, maybe I didn’t import ImageShow the right way?

I also tried using

imageA.show(command='fim')

But it yields the same results

I’m new to coding with Python (and in general), so maybe I’m just doing something stupid without realizing it

Asked By: Dubious Shrub

||

Answers:

Updated Answer

I think newer versions of PIL/Pillow use the xdg-open command to display images. Internally, PIL/Pillow saves your in-memory image as a PNG file on disk and calls the OS’s viewer to view that on-disk PNG. So, I presume there must be a way to set the default viewer for MIME-type "image/png" to be the viewer of your choice, but as a Mac user, I am unsure how you would do that – I guess it is possible with the xdg-mime command.

Original Answer

I think PIL/Pillow works something like this when displaying on Unix/Linux systems:

  • it expects and hopes to find display which is part of ImageMagick
  • it will use eog "Eye of Gnome" if it finds it
  • it will fall back to xv

So, there are a number of possibilities depending on your skill-set, patience, disk-space, desire to use a specific viewer. I don’t know those parameters, so here are some possibilities:

Option: Install ImageMagick with:

sudo apt install imagemagick

Option: Install eog with:

sudo apt install eog

Option: Install xv – I don’t have the exact command to hand

Option: Install feh or some other viewer and symlink it to display so PIL/Pillow thinks it is using ImageMagick display

sudo apt install feh
sudo ln -s /usr/bin/feh /usr/bin/display

Another option might be to create a custom viewer as a derived class from PIL’s UnixViewer that places itself at the top of the list of viewers so it is used first.

So, create a file called "CustomViewer.py" that looks like this – mine uses the feh viewer but you can use any application you like:

#!/usr/bin/env python3

import shutil
import sys

from PIL import Image, ImageShow

class CustomViewer(ImageShow.UnixViewer):
   format = "PNG"
   options = {"compress_level": 1}

   def get_command_ex(self, file, **options):
      command = executable = "feh"
      return command, executable

if shutil.which("feh"):
   print(f'Registering custom viewer for PIL')
   ImageShow.register(CustomViewer, order=-1) # Insert as primary viewer

Then, in your regular Python code where you want to use your custom viewer, just add:

import CustomViewer

and it will output a message saying it is loaded and any subsequent calls to show() will use your custom viewer.

Answered By: Mark Setchell