To answer the original question directly: Tkinter does not currently support JPG images, and PNG support is dependent on the system's version of Tcl/Tk - a separate library, written in C, which Python interfaces with through Tkinter (hence the "inter" part). The popular third-party library pillow
provides a drop-in replacement for the Tkinter PhotoImage
class, allowing it to support many more image formats.
Image formats supported by Tkinter
The Tcl/Tk manual describes support for two separate image types - bitmap
and photo
- described thus:
A bitmap is an image whose pixels can display either of two colors or be transparent.
A photo is an image whose pixels can display any color or be transparent. A photo image is stored internally in full color (32 bits per pixel), and is displayed using dithering if necessary.
These are reflected in Tkinter as the BitmapImage
and PhotoImage
classes, respectively. The formats supported by Tkinter will depend slightly on what version of Tcl/Tk is installed. However, starting with 3.10, a threaded build of Tcl/Tk 8.6 is included with official Python binary releases
The Python Tkinter documentation is mainly focused on explaining functionality that Tkinter adds on top of Tcl/Tk. For most things, the user is expected to refer to the Tcl/Tk documentation (or third-party sources; the Python documentation offers a few suggestions) and understand how the interface works generally.
As pointed out by Donal Fellows on another Stack Overflow question, Tcl/Tk cannot handle individual memory allocations over about 2GB, which theoretically limits image sizes.
Tcl/Tk bitmap
s are much more limited than photo
s, so practically speaking, PhotoImage
will be used much more often. But for completeness: BitmapImage
supports BMP (cross-platform), XPM (for pixmap / colored bitmaps, mainly on X11) and ICO formats (ICO is a special bitmap mostly used for Windows icons).
As explained in the Tcl/Tk documentation, a photo
can be created from a data string containing the raw image data:
The string should contain binary data or, for some formats, base64-encoded data (this is currently guaranteed to be supported for PNG and GIF images).
PhotoImage
supports GIF, PPM and PGM images regardless of Tcl/Tk version.
Tcl/Tk version 8.4 is required to support transparency. (However, as the 8.3 branch has not been maintained since 2002, it is practically guaranteed that a current Python installation with Tkinter support will have transparency support.)
Tcl/Tk version 8.6 adds support for PNG images. If possible, images will be gamma-corrected:
In addition, the implementation should... [a]llow application of display gamma (if known) in conjunction with the gAMA
chunk of imported images, if present, through -format "png -gamma value"
.
SVG support is planned (with some limitations) in Tcl/Tk 8.7 (currently in alpha). JPEG support might be included in the future, if copyright concerns can be resolved.
In addition, there are several ways to extend the default library support:
Verifying image formats
Many other problems with Tkinter image support asked about on Stack Overflow turn out to be caused by an image that is, quite simply, not in the format the programmer expected. Note well that simply renaming a file to have the appropriate suffix will not help if Tkinter does not already support the image format. The suffix is just a hint as to what data to expect in a file. (The underlying Tcl/Tk library also allows for specifying a format explicitly, but mainly it is deduced from the suffix and/or the data itself.)
Here are some ways to verify the format of an image:
Open it with an image-editing program. (Re-saving the image in a specified format is by far the easiest way to fix a problem with an unsupported format, anyway, so this is often the most practical approach.)
Use a command-line tool, such as the file
command on Linux.
Programmatically, open the file and inspect the first few bytes, for example using the third-party filetype package.
Simply use exception handling (try
/except
) and fall back to a placeholder image if the desired image isn't supported. (This may be necessary anyway in case e.g. the image is corrupted or missing.)