Insert an JPG image in Python using Tkinter - python

i'm trying to insert an image using Tkinter but it doesn't work, there is an error message saying : (In fact it is saying that python can't recognise the data in image file)
Traceback (most recent call last):
File "E:/Tle/ISN/Programs (Pyhton)/IMC (Widget) ULTIMATE.py", line 10, in <module>
my_image = PhotoImage(file="C:/Users/mateo.PCMATEO/Pictures/MonCoachPersonnel.jpg")
File "C:\Users\mateo.PCMATEO\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 3545, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Users\mateo.PCMATEO\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 3501, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't recognize data in image file "C:/Users/mateo.PCMATEO/Pictures/MonCoachPersonnel.jpg"
And here's the code i've entered :
from tkinter import*
import tkinter as tk
window = tk.Tk()
window.title("My Personnal Fitness Coach")
window.geometry("400x500")
window.configure(background='grey')
canvas = Canvas(window, width = 100, height = 100)
canvas.pack
my_image = PhotoImage(file="C:/Users/mateo.PCMATEO/Pictures/MonCoachPersonnel.jpg")
canvas.create_image(0, 0, anchor = NW, image=my_image)
window.mainloop()
The problem is that i don't have any modules except the ones predownloaded with python and i don't want to install some yet. So could you help me?

if you use jpg you must do so
from PIL import ImageTk
then
my_image = ImageTk.PhotoImage(file="MonCoachPersonnel.jpg")
canvas.create_image(50, 50, image=my_image, anchor=NW)
I've simplify the file dir, note that I've increase the dimension of the pic, from 0,0 to 50,50.

Please, try this (only change image file path)
from tkinter import*
import tkinter as tk
from PIL import ImageTk, Image
window = tk.Tk()
window.title("My Personnal Fitness Coach")
window.geometry("400x500")
window.configure(background='grey')
canvas = Canvas(window, width = 100, height = 100)
canvas.pack()
photo_image = ImageTk.PhotoImage(Image.open('xxxx\\racecar.jpg'))
my_image = canvas.create_image(0, 0, image=photo_image, anchor=NW)
# my_image = PhotoImage(file="xxxx\\racecar.jpg")
# canvas.create_image(0, 0, anchor = NW, image=my_image)
window.mainloop()

Related

"_tkinter.TclError: image "pyimage2" doesn't exist"

I'm trying to fix this and I don't know how... When I click on the first button the second doesn't appear. It raises this exception:
_tkinter.TclError: image "pyimage2" doesn't exist
I tried everything but I don't know what to do anymore.
Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "test\main.py", line 26, in <lambda>
boutonAlphabetMaj.bind("<Leave>", lambda e: boutonAlphabetMaj.config(fg='#3f3f3f', bg='#383838'))
File "C:\Program Files\Python39\lib\tkinter\__init__.py", line 1646, in configure
return self._configure('configure', cnf, kw)
File "C:\Program Files\Python39\lib\tkinter\__init__.py", line 1636, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: image "pyimage2" doesn't exist
Code:
import tkinter as tk
from tkinter import font
from PIL import ImageTk, Image
import time
import os
# Root
root = tk.Tk()
root.minsize(1920, 1080)
root.maxsize(1920, 1080)
# Frame + Canvas
frame = tk.LabelFrame(root, borderwidth=0)
canvas = tk.Canvas(frame, height=1080, width=1920, borderwidth=0, bg="#383838")
frame.grid()
canvas.grid()
# Fonctions
def alphabet() :
canvas.delete("boutonAlphabet")
# Bouton Alphabet Majuscule
pathAlphabetMaj = os.path.join("test/alphabetMaj.png")
pictureAlphabetMaj = Image.open(pathAlphabetMaj)
picAlphabetMaj = ImageTk.PhotoImage(pictureAlphabetMaj)
boutonAlphabetMaj = tk.Button(canvas, image=picAlphabetMaj, borderwidth=0, bg="#383838", activebackground="#4a4a4a", cursor="hand2")
picAlphabetMaj.pictureAlphabetMaj = pictureAlphabetMaj
boutonAlphabetMaj.bind("<Enter>", lambda e: boutonAlphabetMaj.config(fg='#383838', bg='#3f3f3f'))
boutonAlphabetMaj.bind("<Leave>", lambda e: boutonAlphabetMaj.config(fg='#3f3f3f', bg='#383838'))
canvas.create_window(200, 500, window=boutonAlphabetMaj, tags=("boutonAlphabetMaj"))
# Titre
canvas.create_text(960, 50, text="APPRENDRE LE FRANÇAIS", font=("",50), fill="white")
# Bouton Alphabet
pathAlphabet = os.path.join("test/alphabet.png")
pictureAlphabet = Image.open(pathAlphabet)
picAlphabet = ImageTk.PhotoImage(pictureAlphabet)
boutonAlphabet = tk.Button(canvas, image=picAlphabet, borderwidth=0, bg="#383838", activebackground="#4a4a4a", command=lambda: alphabet(), cursor="hand2")
picAlphabet.pictureAlphabet = pictureAlphabet
boutonAlphabet.bind("<Enter>", lambda e: boutonAlphabet.config(fg='#383838', bg='#3f3f3f'))
boutonAlphabet.bind("<Leave>", lambda e: boutonAlphabet.config(fg='#3f3f3f', bg='#383838'))
canvas.create_window(200, 250, window=boutonAlphabet, tags=("boutonAlphabet"))
# loop
root.mainloop()
You have common problem with bug in ImagePhoto which removes image when it is assigned to local variable in function. You have to assign it to global variable or to class.
It seems you try to resolve this problem but you use wrong variables.
You assign Image.open() to PhotoImage .
picAlphabetMaj.pictureAlphabetMaj = pictureAlphabetMaj
but you should assign PhotoImage to button boutonAlphabetMaj
boutonAlphabetMaj.pictureAlphabetMaj = picAlphabetMaj

Tkinter cannot draw to another window

I want to do something that should be rather simple, but I'm struggling to make it work.
Basically I have 2 Tkinter windows (canvas_tk and control_tk).
In canvas_tk I want to show an image and draw a circle on top of it.
In control_tk I have an Entry to input the radius of the circle to be drawn.
In my code the critical line is at the very bottom of the code:
self.panel = tk.Label(canvas_tk, image=image)
If I make the label in the control_tk or if I dont specify the parent, it actually works fine and draws the circles in the control_tk window
However I want the circles to be drawn in the canvas_tk window
self.panel = tk.Label(image=image) # Works
self.panel = tk.Label(control_tk, image=image) # Works
self.panel = tk.Label(canvas_tk, image=image) # Fails
Here's my minimal code:
import tkinter as tk
from PIL import Image, ImageTk, ImageDraw
control_tk = tk.Tk()
canvas_tk = tk.Tk()
control_tk.geometry("300x300")
canvas_tk.geometry("900x900")
class Drawing:
def __init__(self):
# Numerical entry with a variable traced with callback to "on_change" function
self.radius_var = tk.IntVar()
self.radius_var.trace_variable("w", self.on_change)
tk.Entry(control_tk, textvariable=self.radius_var).grid()
# Initialize image and panel
self.image = Image.new('RGB', (1000, 1000))
self.panel = None
# mainloop for the two tkinter windows
control_tk.mainloop()
canvas_tk.mainloop()
def on_change(self, *args):
print("Value changed") # to check that function is being called
draw = ImageDraw.Draw(self.image)
draw.ellipse((50-self.radius_var.get(), 50-self.radius_var.get(),
50+self.radius_var.get(), 50+self.radius_var.get()),
outline='blue', width=3)
image = ImageTk.PhotoImage(self.image)
if self.panel: # update the image
self.panel.configure(image=image)
self.panel.image = image
else: # if it's the first time initialize the panel
self.panel = tk.Label(canvas_tk, image=image)
self.panel.image = image
self.panel.grid(sticky="w")
Drawing()
And the traceback error basically complains about image not existing
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 508, in get
return self._tk.getint(value)
_tkinter.TclError: expected integer but got ""
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/GIT/142-277-00_pyScuti2/test.py", line 29, in on_change
draw.ellipse((50-self.radius_var.get(), 50-self.radius_var.get(),
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 510, in get
return int(self._tk.getdouble(value))
_tkinter.TclError: expected floating-point number but got ""
Value changed
Value changed
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/GIT/142-277-00_pyScuti2/test.py", line 38, in on_change
self.panel = tk.Label(canvas_tk, image=image)
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 2766, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 2299, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "pyimage1" doesn't exist
First of all, you should not use multiple Tk() instances. Second, you better not using trace() on tracking input change, use bind('<Return>', ...) to trigger drawing after user enters value and press Enter key. Below is a modified code based on yours:
import tkinter as tk
from PIL import Image, ImageTk, ImageDraw
control_tk = tk.Tk()
control_tk.geometry("300x300+800+600")
canvas_tk = tk.Toplevel() # use Toplevel instead of Tk
canvas_tk.geometry("900x900+10+10")
class Drawing:
def __init__(self):
# Numerical entry with a variable traced with callback to "on_change" function
self.radius_var = tk.IntVar()
entry = tk.Entry(control_tk, textvariable=self.radius_var)
entry.grid()
# binding Enter key on entry to trigger the drawing
entry.bind('<Return>', self.on_change)
# Initialize image and panel
self.image = Image.new('RGB', (1000, 1000))
self.panel = None
# mainloop for the main window
control_tk.mainloop()
def on_change(self, *args):
try:
radius = self.radius_var.get()
except:
print('Invalid number')
return
print("Value changed") # to check that function is being called
draw = ImageDraw.Draw(self.image)
draw.ellipse((50-radius, 50-radius, 50+radius, 50+radius),
outline='blue', width=3)
image = ImageTk.PhotoImage(self.image)
if self.panel:
self.panel.configure(image=image)
else:
self.panel = tk.Label(canvas_tk, image=image)
self.panel.grid(sticky='w')
self.panel.image = image
Drawing()

Resizing image Python Tkinter

Hello I am having issues with resizing my picture. I am trying to resize the image to fit the blue drawing. However the way I am doing it, returns an error.
File "gui.py", line 42, in fileDialog
self.display = Label(image=self.photo.resize((800, 600),Image.ANTIALIAS))
AttributeError: 'PhotoImage' object has no attribute 'resize
I am just testing it to see if it fits by doing 800,600 I really don't know.
def fileDialog(self):
self.filename = filedialog.askopenfilename(title="Select")
self.label = ttk.Label(self.labelFrame, text="")
self.label.grid(column=1, row=2)
self.label.configure(text=self.filename)
self.photo= ImageTk.PhotoImage(file = self.filename)
self.display = Label(image=self.photo.resize((800, 600),Image.ANTIALIAS))
self.display.grid(row=0)
Is there something that I am doing incorrectly? Please advise.
You need to resize the image, not the photoimage.
import tkinter as tk
from PIL import Image, ImageTk
filename = 'bell.jpg'
img = Image.open(filename)
resized_img = img.resize((200, 100))
root = tk.Tk()
root.photoimg = ImageTk.PhotoImage(resized_img)
labelimage = tk.Label(root, image=root.photoimg)
labelimage.pack()
To address the new question, you do not have to know the filename at the time of label creation. The following code produces the same result:
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
labelimage = tk.Label(root)
labelimage.pack()
filename = 'bell.jpg'
img = Image.open(filename)
resized_img = img.resize((200, 100))
root.photoimg = ImageTk.PhotoImage(resized_img)
labelimage.configure(image=root.photoimg)

when trying to create a bitmap: _tkinter.TclError: bitmap "pyimage2" not defined

There is an image which I'd like to draw in different colors, so I converted it to a bitmap, but when trying to create it on the canvas I get an error.
This is the code:
import PIL.Image
from PIL import ImageTk
from tkinter import *
im = PIL.Image.open("lightbulb.gif")
small_im = im.resize((20,20), resample=PIL.Image.NEAREST).convert('1');
root = Tk()
canvas = Canvas(root,width=100,height=100,bg='black')
canvas.pack()
bitmap = ImageTk.BitmapImage(small_im)
bitmap_id = canvas.create_bitmap(3,3,background='', foreground='gray', bitmap=bitmap,
anchor=NW)
root.mainloop()
I get the following error:
Traceback (most recent call last):
File "/Users/ronen/Dropbox/trycanvas/bitmaps.py", line 13, in <module>
bitmap_id = canvas.create_bitmap(3,3,background="", foreground="gray", bitmap=bitmap, anchor=NW)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 2486, in create_bitmap
return self._create('bitmap', args, kw)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 2480, in _create
*(args + self._options(cnf, kw))))
_tkinter.TclError: bitmap "pyimage2" not defined
What am I doing wrong?
The tkinter canvas.create_bitmap() method expects its bitmap= option to be a string containing either the name of one of the standard bitmaps (which are 'error', 'gray75', 'gray50', 'gray25', 'gray12', 'hourglass', 'info', 'questhead', 'question', and 'warning') and which look like this:
Or the pathname of a file with one of your own in it in .xbm file format prefixed with an # character.
Below is how to modify your code so it saves the image you want to display in a temporary .xbm format file and then tells tkinter to use that:
import os
import PIL.Image
from PIL import ImageTk
from tempfile import NamedTemporaryFile
import tkinter as tk
im = PIL.Image.open("lightbulb.gif")
small_img = im.resize((20,20), resample=PIL.Image.NEAREST).convert('1');
with NamedTemporaryFile(suffix='.xbm', delete=False) as temp_img:
small_img.save(temp_img.name)
root = tk.Tk()
canvas = tk.Canvas(root, width=100, height=100, bg='black')
canvas.pack()
bitmap_id = canvas.create_bitmap(3, 3, background='', foreground='gray',
bitmap='#'+temp_img.name, anchor=tk.NW)
root.mainloop()
try: # Cleanup
os.remove(temp_img.name) # Get rid of named temporary file.
except FileNotFoundError:
pass
Okay, I now understand what's going on. ImageTk.BitmapImage actually return an image, not a bitmap, but it can be used to change the colors. So intead of:
bitmap = ImageTk.BitmapImage(small_im)
bitmap_id = canvas.create_bitmap(3,3,background='', foreground='gray', bitmap=bitmap,
anchor=NW)
I should have coded:
from_bitmap = ImageTk.BitmapImage(small_im, background='', foreground='gray')
bitmap_id = canvas.create_image(3,3, image=from_bitmap, anchor=NW)

How to open PIL Image in Tkinter on Canvas

I can't seem to get my PIL Image to work on canvas. Code:
from Tkinter import*
import Image, ImageTk
root = Tk()
root.geometry('1000x1000')
canvas = Canvas(root,width=999,height=999)
canvas.pack()
image = ImageTk.PhotoImage("ball.gif")
imagesprite = canvas.create_image(400,400,image=image)
root.mainloop()
Error:
Traceback (most recent call last):
File "C:/Users/Mark Malkin/Desktop/3d Graphics Testing/afdds.py", line 7, in <module>
image = ImageTk.PhotoImage("ball.gif")
File "C:\Python27\lib\site-packages\PIL\ImageTk.py", line 109, in __init__
mode = Image.getmodebase(mode)
File "C:\Python27\lib\site-packages\PIL\Image.py", line 245, in getmodebase
return ImageMode.getmode(mode).basemode
File "C:\Python27\lib\site-packages\PIL\ImageMode.py", line 50, in getmode
return _modes[mode]
KeyError: 'ball.gif'
I need to use PIL images not PhotoImages because I want to resize my images. Please don't suggest switching to Pygame because I want to use Tkinter.
Try creating a PIL Image first, then using that to create the PhotoImage.
from Tkinter import *
import Image, ImageTk
root = Tk()
root.geometry('1000x1000')
canvas = Canvas(root,width=999,height=999)
canvas.pack()
pilImage = Image.open("ball.gif")
image = ImageTk.PhotoImage(pilImage)
imagesprite = canvas.create_image(400,400,image=image)
root.mainloop()
(An old question, but the answers so far are only half-complete.)
Read the docs:
class PIL.ImageTk.PhotoImage(image=None, size=None, **kw)
image – Either a PIL image, or a mode string. [...]
file – A filename to load the image from (using Image.open(file)).
So in your example, use
image = ImageTk.PhotoImage(file="ball.gif")
or explicitly
image = ImageTk.PhotoImage(Image("ball.gif"))
(And remember – as you did correctly: Keep a reference to the image object in your Python program, otherwise it is garbage-collected before you seee it.)
You can import multiple image formats, and resize with this code. "basewidth" sets the width of your image.
from Tkinter import *
import PIL
from PIL import ImageTk, Image
root=Tk()
image = Image.open("/path/to/your/image.jpg")
canvas=Canvas(root, height=200, width=200)
basewidth = 150
wpercent = (basewidth / float(image.size[0]))
hsize = int((float(image.size[1]) * float(wpercent)))
image = image.resize((basewidth, hsize), PIL.Image.ANTIALIAS)
photo = ImageTk.PhotoImage(image)
item4 = canvas.create_image(100, 80, image=photo)
canvas.pack(side = TOP, expand=True, fill=BOTH)
root.mainloop()
I was banging my head against the wall for a while on this issue until I found the following:
http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm
Apparently, Python's garbage collector can trash the ImageTk object. I imagine apps using alot of widgets (like mine) are more susceptible to this behavior.

Categories

Resources