wxPython GUI to Display a JPEG (.jpg) Image

vegaseat 0 Tallied Votes 3K Views Share

Jumping through a few extra hoops allows you to display the common image format jpeg on a panel of the wxPython GUI window. All you need to do is to read in the image file as a binary, convert to a byte stream image and then to a bitmap. Now you can display the bitmap. An updated simpler way without the stream is also shown.

# show a jpeg (.jpg) image using wxPython, newer coding style
# two different ways to load and display are given
# tested with Python24 and wxPython25   vegaseat   24jul2005

import wx
import  cStringIO

class Panel1(wx.Panel):
  """ class Panel1 creates a panel with an image on it, inherits wx.Panel """
  def __init__(self, parent, id):
    # create the panel
    wx.Panel.__init__(self, parent, id)
    try:
        # pick a .jpg file you have in the working folder
        imageFile = 'Moo.jpg'
        data = open(imageFile, "rb").read()
        # convert to a data stream
        stream = cStringIO.StringIO(data)
        # convert to a bitmap
        bmp = wx.BitmapFromImage( wx.ImageFromStream( stream ))
        # show the bitmap, (5, 5) are upper left corner coordinates
        wx.StaticBitmap(self, -1, bmp, (5, 5))
        
        # alternate (simpler) way to load and display a jpg image from a file
        # actually you can load .jpg  .png  .bmp  or .gif files
        jpg1 = wx.Image(imageFile, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        # bitmap upper left corner is in the position tuple (x, y) = (5, 5)
        wx.StaticBitmap(self, -1, jpg1, (10 + jpg1.GetWidth(), 5), (jpg1.GetWidth(), jpg1.GetHeight()))
    except IOError:
        print "Image file %s not found" % imageFile
        raise SystemExit


app = wx.PySimpleApp()
# create a window/frame, no parent, -1 is default ID
# increase the size of the frame for larger images
frame1 = wx.Frame(None, -1, "An image on a panel", size = (400, 300))
# call the derived class
Panel1(frame1,-1)
frame1.Show(1)
app.MainLoop()

Dani AI

Generated

Nice work, . For the follow-ups from and @Erik Vandamme: two things are tripping you up.

  1. PIL.Image.show() launches the OS image viewer, so it will pop Windows Picture and Fax Viewer instead of drawing inside your wx frame. That method saves a temporary file and opens it in an external viewer by design. Remove .show() and render with a wx.StaticBitmap (or the generic variant) on your panel. (pillow.readthedocs.io)

  2. Simply changing a filename variable will not update what is on screen. Keep a reference to the widget that is showing the image and call SetBitmap(...) with a new wx.Bitmap whenever you want to change the picture. If the image size changes, call Layout() so sizers recalc.

Here is a compact, modern (wxPython 4, Python 3) pattern for a slideshow that updates the same control and scales to the client area:

import wx

class Viewer(wx.Frame):
    def __init__(self, images):
        super().__init__(None, title="Slideshow"); p = wx.Panel(self)
        self.bmp = wx.StaticBitmap(p); self.images, self.i = images, 0
        s = wx.BoxSizer(wx.VERTICAL); s.Add(self.bmp, 1, wx.EXPAND|wx.ALL, 8); p.SetSizer(s)
        self.timer = wx.Timer(self); self.Bind(wx.EVT_TIMER, self.on_tick, self.timer); self.timer.Start(2000)
        self.show(self.images[0])

    def show(self, path):
        w, h = self.ClientSize
        img = wx.Image(path, wx.BITMAP_TYPE_ANY).Scale(max(1, w), max(1, h), wx.IMAGE_QUALITY_HIGH)
        self.bmp.SetBitmap(wx.Bitmap(img)); self.Layout()

    def on_tick(self, _):
        self.i = (self.i + 1) % len(self.images); self.show(self.images[self.i])

app = wx.App(); Viewer(["C:/eTemp/a.jpg", "C:/eTemp/b.jpg"]).Show(); app.MainLoop()

Tips:

  • Use forward slashes or raw strings for Windows paths (e.g., r"C:\eTemp\a.jpg").
  • For portable scaling and larger images, consider wx.GenericStaticBitmap and its scale modes. (docs.wxpython.org)
  • A slideshow is easiest with wx.Timer; keep a reference to the timer and stop it on close. (docs.wxpython.org)
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Adopted the newer wxPython coding style, which identifies the namespace wx.

feci1024 0 Newbie Poster

Hello,
let me just say that I found you example very useful. I've tried to make a simple slideshow program from it, but I'm stuck, because I can't make the picture change in the created Panel. I would appreciate any help. Thank you.

Erik Vandamme 0 Newbie Poster

When iI supply the name of another file in filebname="NEWONE.JPG" the display does not change ...

Erik Vandamme 0 Newbie Poster

When I try to integrate this into wxPython (windows XP) see code below.
It actually use the windows fax and picture viewer, so I obviously need to somehow fix the image to the frame/panel??
# show a jpeg (.jpg) image using wxPython, newer coding style
# two different ways to load and display are given
# tested with Python24 and wxPython25 vegaseat 24jul2005

import wx
import Image
import cStringIO


class Panel1(wx.Panel):
""" class Panel1 creates a panel with an image on it, inherits wx.Panel """
def __init__(self, parent, id):
# create the panel
wx.Panel.__init__(self, parent, id)
try:
# pick a .jpg file you have in the working folder
imageFile = 'c:\eTemp\dThumb.jpg'
im1 = Image.open(imageFile)
im1.show()
## data = open(imageFile, "rb").read()
## # convert to a data stream
## stream = cStringIO.StringIO(data)
## # convert to a bitmap
## bmp = wx.BitmapFromImage( wx.ImageFromStream( stream ))
## # show the bitmap, (5, 5) are upper left corner coordinates
## wx.StaticBitmap(self, -1, bmp, (5, 5))

# alternate (simpler) way to load and display a jpg image from a file
# actually you can load .jpg .png .bmp or .gif files
print "next\n"
imageFile = 'c:\eTemp\TOPUPDOWN.jpg'
im1 = Image.open(imageFile)
im1.show()

jpg1 = wx.Image(imageFile, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
# bitmap upper left corner is in the position tuple (x, y) = (5, 5)
wx.StaticBitmap(self, -1, jpg1, (10 + jpg1.GetWidth(), 5), (jpg1.GetWidth(), jpg1.GetHeight()))
except IOError:
print "Image file %s not found" % imageFile
raise SystemExit


app = wx.PySimpleApp()
# create a window/frame, no parent, -1 is default ID
# increase the size of the frame for larger images
frame1 = wx.Frame(None, -1, "An image on a panel", size = (400, 300))
# call the derived class
Panel1(frame1,-1)
frame1.Show(1)
app.MainLoop()

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.