Tkinter error: Couldn't recognize data in image file
Question:
I’m trying to put a jpg image to a tkinter canvas. tkinter gives me this error:
couldn’t recognize data in image file
I use the code from the documentation:
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = PhotoImage(file="bll.jpg")
canv.create_image(20,20, anchor=NW, image=img)
Same thing with png images. Even tried to put an image into a label widget, but got the same error. What’s wrong?
I am using Python 3 on Mac. Python file and image are in the same folder.
Answers:
Your code seems right, this is running for me on Windows 7 (Python 3.6):
from tkinter import *
root = Tk()
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = PhotoImage(file="bll.jpg")
canv.create_image(20,20, anchor=NW, image=img)
mainloop()
resulting in this tkinter GUI:
(imgur converted it to bll.png
but this is working for me as well.)
More options:
- This answer mentions, tkinter is working only with
gif
images. Try using a .gif
image.
- If this is not working, use
PIL
as stated in this answer.
Update: Solution with PIL
:
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = ImageTk.PhotoImage(Image.open("bll.jpg")) # PIL solution
canv.create_image(20, 20, anchor=NW, image=img)
mainloop()
I was getting the same issue. I have windows and Python 3.6. So I found two solutions for this either you use/convert to .png
image (with the same function you have used):
photo = PhotoImage('xyz.png')
l = Label(image = photo)
l.pack()
or if you want to read .jpg
file only then use PIL library to read and display an image like this:
from PIL import ImageTk, Image
img = ImageTk.PhotoImage(Image.open("xyz.jpg"))
l=Label(image=img)
l.pack()
Install PIL/Pillow with:
pip install Pillow
or:
sudo pip install pillow
from PIL import Image
from PIL import ImageTk
import tkinter
image = Image.open('bll.jpg')
image = image.resize((20, 20))
image = ImageTk.PhotoImage(image)
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = PhotoImage(file=image)
Also using .PNG instead of .JPG is better for Tkinter.
Another alternative solution:
filename = ImageTk.PhotoImage(Image.open('imagename.jpeg' ))
background_label = tk.Label(self.root, image=filename)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
Install the OpenCV packages for Python:
pip install opencv-python
Then try this code:
import cv2
Img = cv2.imread("xxxxx.png")
cv2.imwrite("xxxxx.png",img)
# Your code goes here!
This error could possibly happen because of relative file path
or non-English
characters in filepath. So I made this function which works very good in windows and with any kinds of file paths:
def loadrelimages(relativepath):
from PIL import ImageTk, Image
import os
directory_path = os.path.dirname(__file__)
file_path = os.path.join(directory_path, relativepath)
img = ImageTk.PhotoImage(Image.open(file_path.replace('\', "/")))
return img
For example, load photo_2021-08-16_18-44-28.jpg
which is at the same directory with this code:
from tkinter import *
import os
def loadrelimages(relativepath):
from PIL import ImageTk, Image
import os
directory_path = os.path.dirname(__file__)
file_path = os.path.join(directory_path, relativepath)
img = ImageTk.PhotoImage(Image.open(file_path.replace('\',"/")))
return img
root = Tk()
canvas = Canvas(root, width=500, height=500)
canvas.pack()
loadedimage=loadrelimages('photo_2021-08-16_18-44-28.jpg')
canvas.create_image(250, 250, image=loadedimage)
root.mainloop()
Using Python package Pillow worked for me.
Just do pip install pillow.
Then use ImageTk.PhotoImage(Image.open("Your image path goes here…")) instead of tkinter.PhotoImage()
# in terminal pip install pillow
from tkinter import *
from PIL import Image, ImageTk
a_root = Tk()
# WINDOW SIZING
a_root.geometry("600x400")
a_root.minsize(400, 400)
a_root.maxsize(800, 800)
# for PNG IMG
# photo = PhotoImage(file="mark1.png")
# for JPG IMG
image = Image.open("mark.jpg")
photo = ImageTk.PhotoImage(image)
img_label = Label(image=photo)
img_label.pack()
a_root.mainloop()
I was getting the same error. You just have to use a PNG file instead of a jpeg/jpg.
if you dont have a png version you can convert your picture here —> https://cloudconvert.com/
from tkinter import *
root = Tk()
root.geometry("1920x1080")
photo = PhotoImage(file="Akatsuki.png")
label = Label(image=photo)
label.pack()
root.mainloop()
Your version of Tkinter doesn’t support jpg.
I fix it by installing python 3.10 which has built-in 8.6.11 Tcl/Tk.
https://www.python.org/download/mac/tcltk/
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.
The BitmapImage class
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).
The PhotoImage class
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:
- TCL extensions such as Img and tclimage
- Custom handlers written using Tcl’s C API: see TkCreatePhotoImageFormat
- Python extensions: pillow supports a variety of formats that can all be converted using the ImageTk module
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.)
I’m trying to put a jpg image to a tkinter canvas. tkinter gives me this error:
couldn’t recognize data in image file
I use the code from the documentation:
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = PhotoImage(file="bll.jpg")
canv.create_image(20,20, anchor=NW, image=img)
Same thing with png images. Even tried to put an image into a label widget, but got the same error. What’s wrong?
I am using Python 3 on Mac. Python file and image are in the same folder.
Your code seems right, this is running for me on Windows 7 (Python 3.6):
from tkinter import *
root = Tk()
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = PhotoImage(file="bll.jpg")
canv.create_image(20,20, anchor=NW, image=img)
mainloop()
resulting in this tkinter GUI:
(imgur converted it to bll.png
but this is working for me as well.)
More options:
- This answer mentions, tkinter is working only with
gif
images. Try using a.gif
image. - If this is not working, use
PIL
as stated in this answer.
Update: Solution with PIL
:
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = ImageTk.PhotoImage(Image.open("bll.jpg")) # PIL solution
canv.create_image(20, 20, anchor=NW, image=img)
mainloop()
I was getting the same issue. I have windows and Python 3.6. So I found two solutions for this either you use/convert to .png
image (with the same function you have used):
photo = PhotoImage('xyz.png')
l = Label(image = photo)
l.pack()
or if you want to read .jpg
file only then use PIL library to read and display an image like this:
from PIL import ImageTk, Image
img = ImageTk.PhotoImage(Image.open("xyz.jpg"))
l=Label(image=img)
l.pack()
Install PIL/Pillow with:
pip install Pillow
or:
sudo pip install pillow
from PIL import Image
from PIL import ImageTk
import tkinter
image = Image.open('bll.jpg')
image = image.resize((20, 20))
image = ImageTk.PhotoImage(image)
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = PhotoImage(file=image)
Also using .PNG instead of .JPG is better for Tkinter.
Another alternative solution:
filename = ImageTk.PhotoImage(Image.open('imagename.jpeg' ))
background_label = tk.Label(self.root, image=filename)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
Install the OpenCV packages for Python:
pip install opencv-python
Then try this code:
import cv2
Img = cv2.imread("xxxxx.png")
cv2.imwrite("xxxxx.png",img)
# Your code goes here!
This error could possibly happen because of relative file path
or non-English
characters in filepath. So I made this function which works very good in windows and with any kinds of file paths:
def loadrelimages(relativepath):
from PIL import ImageTk, Image
import os
directory_path = os.path.dirname(__file__)
file_path = os.path.join(directory_path, relativepath)
img = ImageTk.PhotoImage(Image.open(file_path.replace('\', "/")))
return img
For example, load photo_2021-08-16_18-44-28.jpg
which is at the same directory with this code:
from tkinter import *
import os
def loadrelimages(relativepath):
from PIL import ImageTk, Image
import os
directory_path = os.path.dirname(__file__)
file_path = os.path.join(directory_path, relativepath)
img = ImageTk.PhotoImage(Image.open(file_path.replace('\',"/")))
return img
root = Tk()
canvas = Canvas(root, width=500, height=500)
canvas.pack()
loadedimage=loadrelimages('photo_2021-08-16_18-44-28.jpg')
canvas.create_image(250, 250, image=loadedimage)
root.mainloop()
Using Python package Pillow worked for me.
Just do pip install pillow.
Then use ImageTk.PhotoImage(Image.open("Your image path goes here…")) instead of tkinter.PhotoImage()
# in terminal pip install pillow
from tkinter import *
from PIL import Image, ImageTk
a_root = Tk()
# WINDOW SIZING
a_root.geometry("600x400")
a_root.minsize(400, 400)
a_root.maxsize(800, 800)
# for PNG IMG
# photo = PhotoImage(file="mark1.png")
# for JPG IMG
image = Image.open("mark.jpg")
photo = ImageTk.PhotoImage(image)
img_label = Label(image=photo)
img_label.pack()
a_root.mainloop()
I was getting the same error. You just have to use a PNG file instead of a jpeg/jpg.
if you dont have a png version you can convert your picture here —> https://cloudconvert.com/
from tkinter import *
root = Tk()
root.geometry("1920x1080")
photo = PhotoImage(file="Akatsuki.png")
label = Label(image=photo)
label.pack()
root.mainloop()
Your version of Tkinter doesn’t support jpg.
I fix it by installing python 3.10 which has built-in 8.6.11 Tcl/Tk.
https://www.python.org/download/mac/tcltk/
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.
The BitmapImage class
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).
The PhotoImage class
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:
- TCL extensions such as Img and tclimage
- Custom handlers written using Tcl’s C API: see TkCreatePhotoImageFormat
- Python extensions: pillow supports a variety of formats that can all be converted using the ImageTk module
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.)