RuntimeError: Too early to create image [duplicate] - python

This question already has an answer here:
Python Tkinter Error, "Too Early to Create Image"
(1 answer)
Closed 4 years ago.
I am trying to create an image library and to call an image from that image library in tkinter. But this code gives me an error:
This is the image library file img.py:
from tkinter import *
food_0001 = PhotoImage(file='food_0001.gif')
food_0002 = PhotoImage(file='bg.gif')
This is the file intended to open images stored in img.py:
from tkinter import *
import img
window = Tk()
window.title('image')
canvas = Canvas(window, width = 800, height = 800)
canvas.pack()
canvas.create_image(0,0, anchor=NW, image=food_0001)
window.mainloop()

It is because PhotoImage() can only be called after creation of Tk().
Suggest to rewrite img.py to create PhotoImage() only when it is needed. Below is a sample way to do it:
from tkinter import *
imagelist = {
'food_0001': ['food_0001.png', None],
'food_0002': ['bg.png', None],
}
def get(name):
if name in imagelist:
if imagelist[name][1] is None:
print('loading image:', name)
imagelist[name][1] = PhotoImage(file=imagelist[name][0])
return imagelist[name][1]
return None
Then modify your main program to cater the change:
from tkinter import *
import img
window = Tk()
window.title('image')
canvas = Canvas(window, width=800, height=800)
canvas.pack()
canvas.create_image(0, 0, anchor='nw', image=img.get('food_0001'))
window.mainloop()
Of cause there are many other ways to do it and it depends on your imagination.

Related

display image by clicking a button tkinter [duplicate]

This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 9 months ago.
I am trying to display an image in a window with tkinter, by clicking a button.
I created this function :
def tabuim():
tabu = Frame(win, width=600, height=400)
tabu.pack()
tabu.place(anchor='center', relx=0.8, rely=0.35)
img2 = ImageTk.PhotoImage(Image.open("Tabu.jpg"), master=win)
label2 = Label(tabu, image = img2, borderwidth=3, relief="solid")
label2.pack()
with this button :
button2 = Button(win, text = 'Tabu Route Solution', command = tabuim)
button2.place(relx = 0.5, rely = 0.5)
But it partially works. It only show a border without my image...
Thanks for you help
The following example displays a background image in a frame:
Import tkinter
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
Create a photoimage object of the image in the path
image1 = Image.open("<path/image_name>")
test = ImageTk.PhotoImage(image1)
label1 = tkinter.Label(image=test)
label1.image = test
Position image
label1.place(x=<x_coordinate>, y=<y_coordinate>)
root.mainloop()
This an example you can do as instead of resizing before loading the page you could resize after the image is loaded.

How can my program show image when I click button? [duplicate]

This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 10 months ago.
I was trying to show the image when I clicked the button however it failed( the program does not report an error but the image is still not displayed). I'm sure I put the right path to the picture. This is code
import tkinter as tk
from PIL import ImageTk, Image
window = tk.Tk()
def def_btn1():
image1 = Image.open("csdl.png")
image1 = image1.resize((710, 400), Image.ANTIALIAS)
test = ImageTk.PhotoImage(image1)
lbl2 = tk.Label(image=test)
lbl2.pack()
btn1 = tk.Button(text="click to show", relief=tk.RIDGE, width=15, font=(12),command=def_btn1)
btn1.pack()
window = tk.mainloop()
I want when I click the button the image will show in the program. Thank you!
You need to add lbl2.image = test for the image to not be destroyed by tkinter, you new code should be this -
import tkinter as tk
from PIL import ImageTk, Image
window = tk.Tk() # You might want to move this line below your functions, with the other global variables
def def_btn1():
image1 = Image.open("csdl.png")
image1 = image1.resize((710, 400), Image.ANTIALIAS)
test = ImageTk.PhotoImage(image1)
lbl2 = tk.Label(image=test)
lbl2.image = test # You need to have this line for it to work, otherwise it is getting rid of the image. the varibale after the '=' must be the same as the one calling "ImageTk.PhotoImage"
lbl2.pack()
btn1 = tk.Button(text="click to show", relief=tk.RIDGE, width=15, font=(12),command= lambda : def_btn1()) # adding 'lambda :' stops the function from running straight away, it will only run if the button is pressed
btn1.pack()
window = tk.mainloop()

Why is my image not showing up in tkinter canvas [duplicate]

This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 2 years ago.
I am trying to make this UI from a stimulus as part of an assessment for school. I tried to import the provided school logo and banner on the top frame of the page and put images on the canvas but have yet to achieve any results. When I run the code, the pictures won't load at all. The code that I was working with is as followed:
from tkinter import *
import random
import time
import sqlite3
from tkinter import simpledialog
from tkinter import messagebox
from tkcalendar import *
from tkinter import ttk
import math
from PIL import Image, ImageTk
import winsound
#-------------Frames setup--------------------------
class VendingApp(Tk):
def __init__(self):
Tk.__init__(self)
self._frame = None
self.switch_frame(Home)
def switch_frame(self, frame_class):
#Destroys current frame and replaces it with a new one.
new_frame = frame_class(self)
if self._frame is not None:
self._frame.destroy()
self._frame = new_frame
self._frame.pack()
####-----------------------Home page---------------------------
class Home(Frame):
def __init__(self, master):
Frame.__init__(self, master)
topFrame = Frame(self,width = 1024, height = 100, bd = 2, bg = "black")
topFrame.pack()
canvas_for_logo = Canvas(topFrame, height=100, width=100, bg = 'green') ##logo image
canvas_for_logo.grid(row=0, column=0, sticky='ne')
img_logo = Image.open("pic/sitelogo.png")
img_logo = img_logo.resize((40,40), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(img_logo)
canvas_for_logo.create_image(0, 0, anchor=NW, image=logo)
canvas_for_banner = Canvas(topFrame, bg='red', height=100, width=924) #banner image
canvas_for_banner.grid(row=0, column=1, sticky='nw')
img_banner = Image.open("pic/banner.jpg")
img_banner = img_banner.resize((40,40), Image.ANTIALIAS)
banner = ImageTk.PhotoImage(img_banner)
canvas_for_banner.create_image(0, 0, anchor=NW, image=banner)
MidFrame = Frame(self,width = 1024, height = 628, bd = 2)
MidFrame.pack()
MidFrame.grid_propagate(False)
BottomFrame = Frame(self,width = 1024, height = 50, bd = 2, bg = "black")
BottomFrame.pack()
BottomFrame.grid_propagate(False)
if __name__ == "__main__":
root = VendingApp()
#Sets the size of the window
root.geometry("1024x768")
#Renames the TITLE of the window
root.title("Vending machine")
root.geometry("1024x768")
root.resizable(False, False)
root.mainloop()
I decided to make a separate file to test if the image would load without class, and it did. Codes are as followed:
from tkinter import ttk
from tkinter import*
import time
from PIL import Image, ImageTk
root = Tk()
canvas_for_logo = Canvas(root, height=100, width=100)
canvas_for_logo.pack()
img = Image.open("pic/sitelogo.png")
img = img.resize((105,105), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(img)
canvas_for_logo.create_image(0, 0, anchor=NW, image=logo)
canvas_for_banner = Canvas(root, bg='red', height=100, width=924) #banner image
canvas_for_banner.pack()
img_banner = Image.open("pic/banner.jpg")
img_banner = img_banner.resize((924,100), Image.ANTIALIAS)
banner = ImageTk.PhotoImage(img_banner)
canvas_for_banner.create_image(0, 0, anchor=NW, image=banner)
root.mainloop()
Can someone please tell me what I did wrong? All replies are much appreciated. Thank you.
This is a typical Tkinter bug. I don't want to go into details cause I don't fully understand why it happens either, but it has something to do with the garbage collector and the fact that it doesn't consider the objects you have created for storing those images like being in use, so it deletes them; or something like that.
Luckily, it has an easy solution: you can either create an internal list variable, let say, self._images that stores each image you are using, something like:
self._images = list()
(...)
self._images.append(logo)
(...)
self._images.append(banner)
Or, you could assign to each canvas instance an attribute image (or img, it doesn't really matters) that stores the image instance it is going to carry. In your code, it will look similar to:
canvas_for_logo.image = logo
(...)
canvas_for_banner.image = banner
This way, you can avoid the garbage collector deleting what it shouldn't, cause now it acknowledges that this instances are being in use.

Python TKinter row of images background [duplicate]

This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 5 years ago.
Issue:
Why does this code not produce a row of 5 images? Ive tried different combinations of pack, place and grid but I can't resolve the issue. I think the current issue is that the backgrounds of images are overlapping each other but i tried reversing the loop to solve the issue and it changed nothing.
Code:
import base64
try:
# Python2
import Tkinter as tk
from urllib2 import urlopen
except ImportError:
# Python3
import tkinter as tk
from urllib.request import urlopen
root = tk.Tk()
root.title("display a row of images")
root.geometry("%dx%d+%d+%d" % (1000, 600, 0, 0))
images = ["C20KEWS", "ANYT6mV", "b3vwblN", "7Y1MG17", "ouXXEMi"]
for image in images:
imgbytes = urlopen("http://i.imgur.com/"+image+".gif").read()
imgb64 = base64.encodestring(imgbytes)
imageTK = tk.PhotoImage(data=imgb64)
imageContainer = tk.Frame(root,
bg="black",
width=200,
height=600
)
print images.index(image)*200, 0
imageContainer.place(x=images.index(image)*200, y=0, width=200, height=600)
imageLabel = tk.Label(imageContainer, image=imageTK, bg='black')
imageLabel.pack(side=tk.LEFT)
root.mainloop()
imageTk is overwritten, and garbage collected. They should be there to be displayed.
Save those ImageTk objects to prevent that.
root = tk.Tk()
root.title("display a row of images")
root.geometry("%dx%d+%d+%d" % (1000, 600, 0, 0))
images = ["C20KEWS", "ANYT6mV", "b3vwblN", "7Y1MG17", "ouXXEMi"]
photo_images = [] # <--------
for image in images:
imgbytes = urlopen("http://i.imgur.com/"+image+".gif").read()
imgb64 = base64.encodestring(imgbytes)
imageTK = tk.PhotoImage(data=imgb64)
photo_images.append(imageTK) # <-----------
imageContainer = tk.Frame(root,
bg="black",
width=200,
height=600
)
print images.index(image)*200, 0
imageContainer.place(x=images.index(image)*200, y=0, width=200, height=600)
imageLabel = tk.Label(imageContainer, image=imageTK, bg='black')
imageLabel.pack(side=tk.LEFT)
root.mainloop()

What is my code's issue ? It should show a selected image in a canvas [duplicate]

This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 5 years ago.
import tkinter as tk
from tkinter import *
from PIL import Image,ImageTk
from PIL import ImageTk
from tkinter import filedialog
import sys
# # #
root=tk.Tk()
root.geometry('1000x690')
root.title("Baccalauréat ISN 2017")
def Open_Image():
Im =Image.open(filedialog.askopenfilename())
# i want to be able to resize the image without deforming it.
Nim = Im.resize((int((Im.width*514)/Im.height), 514)) #maxsize = (821, 514) ---> size of the canvas 821-length; 514 -height
nshow = ImageTk.PhotoImage(Nim)
Can = tk.Canvas(root, background = 'blue')
Can.grid(row = 1, column = 0, rowspan = 6, columnspan = 5, sticky = W + E + N + S)
Cim = Can.create_image(0, 0, anchor = NW, image = nshow)
B13= Button(root, text='Open Image', height=5, width= 25, command = Open_Image)
B13.grid(row=1, column=5, sticky= W + E)
mainloop()
Why is the code not working ? It shows this (a blank canvas), instead of the selected file it should show in its place.
It is likely getting caught in garbage collection. To prevent this, bind it to a reference, i.e. put root. in front of the name you give your image in this case or something similar.

Categories