image dont show on canvas without any error custom tkinter [duplicate] - python

This question already has answers here:
Tkinter vanishing PhotoImage issue [duplicate]
(1 answer)
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 29 days ago.
hello i try to build a simpel watermark app
i user custom tkinter for user interface ( its same to tkinter )
when i upload a picture with button my function everything work expact picture in canvas i see the canvas but i dont see a picture i test the code with a text on canvas and its show when i add a label with same photo ( i comment that line in this cod) even i dont grid it on window my picture show in canvas this is my cod :
import customtkinter
from PIL import Image, ImageTk
my_font1 = ('times', 18, 'bold')
customtkinter.set_appearance_mode("dark")
customtkinter.set_default_color_theme("dark-blue")
window = customtkinter.CTk()
window.title("Water mark Photo")
window.config(padx=50, pady=50)
window.geometry("600x600")
input_pic_label = customtkinter.CTkLabel(master=window,
text="Choose Your Photo",
font=my_font1)
input_pic_label.grid(row=0, column=0, padx=(180, 0), pady=(200, 0))
choose_pic_button = customtkinter.CTkButton(master=window,
text="Upload Photo",
command=lambda: upload_file())
choose_pic_button.grid(row=1, column=0, padx=(180, 0))
def upload_file():
choose_pic_button.destroy()
input_pic_label.destroy()
f_types = [('Jpg Files', '*.jpg'), ('Png Files', '*.png')]
filename = customtkinter.filedialog.askopenfilename(filetypes=f_types)
image = Image.open(filename)
original_image_size = image.size
print(original_image_size)
resized_image = image.resize((500, 500))
resized_image.save("temp.jpg")
new_image = ImageTk.PhotoImage(resized_image)
canvas = customtkinter.CTkCanvas(master=window, width=500, height=500, highlightthickness=0, bg="black")
canvas.grid(row=2, column=1, columnspan=2)
canvas.create_image(250, 250, image=new_image)
window.update()
# label = customtkinter.CTkLabel(master=window, text="", image=new_image)
window.mainloop()
i expect to see a picture but its show nothing i also try to di it in tkinter with the blow cod but output its same expect i get nothing as outpout here without any error:
import tkinter
from PIL import Image, ImageTk
from tkinter import filedialog
my_font1 = ('times', 18, 'bold')
window = tkinter.Tk()
window.title("Water mark Photo")
window.config(padx=50, pady=50)
input_pic_label = tkinter.Label(window,
text="Choose Your Photo",
font=my_font1)
input_pic_label.grid(row=0, column=0, padx=(180, 0))
choose_pic_button = tkinter.Button(window,
text="Upload Photo",
command=lambda: upload_file())
choose_pic_button.grid(row=1, column=0, padx=(180, 0))
canvas = tkinter.Canvas(window, width=500, height=500, highlightthickness=0)
text = canvas.create_text(250, 250, text="Your image")
canvas.grid(row=2, column=1, columnspan=2)
def upload_file():
#choose_pic_button.destroy()
#input_pic_label.destroy()
#canvas.itemconfig(text, text="")
f_types = [('Jpg Files', '*.jpg'), ('Png Files', '*.png')]
filename = tkinter.filedialog.askopenfilename(filetypes=f_types)
image = Image.open(filename)
img = ImageTk.PhotoImage(Image.open(filename))
original_image_size = image.size
print(original_image_size)
resized_image = image.resize((500, 500))
resized_image.save("temp.jpg")
resized_image = ImageTk.PhotoImage(resized_image)
canvas.create_image(250, 250, image=resized_image)
label = tkinter.Label(window, text="helloooooo", image=resized_image)
label.grid(row=2, column=4)
window.mainloop()

Related

Problem with Python tkinter (image does not appear as button)

First: In code below i want to use instead of default rectangle button, images prepared by myslef.
This generates some problems (mayby with reference)? This button does not appear as image, also i am not able to use function (name: load_frame_insert()) after click.
Second: I wonder to have 2 bbtns:
Normal: assets/insert_data.png
OnClick: assets/insert_data2.png
Could you help me?
PS. Doesn't work after moving from up-down code to code with functions
import pyodbc
import pandas as pd
import os
import tkinter as tk
from PIL import ImageTk
# DB connector
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};'
'SERVER=onyx1905;'
'DATABASE=DW_15;'
'Trusted_Connection=yes')
# variables
name = os.getlogin()
cursor = conn.cursor()
running = True
bg_color_1 = "#205E61"
bg_button = "#1B4E51"
bg_button_ac = "#FFD966"
global img_button_1
def image_button_1(size):
img = tk.PhotoImage(file="assets/insert_data.png")
img = img.subsample(size, size)
return img
#button img: insert_data
#button img: insert_data_on_click
def clear_widgets(frame):
for widget in frame.winfo_children():
widget.destroy()
def load_main_frame():
clear_widgets(frame_insert)
frame_main.tkraise()
frame_main.pack_propagate(False)
# widget frame_main logo
logo_image = ImageTk.PhotoImage(file="assets/xrdl_logo.png")
logo_widget = tk.Label(frame_main, image=logo_image, bg=bg_color_1)
logo_widget.image = logo_image
logo_widget.pack()
# label on 1st frame
tk.Label(
frame_main,
text=(f" Hi {name}, please choose an action "),
bg=bg_button,
fg="white",
font=("TkMenuFont", 12)
).pack(pady=10)
# btn code on 1st frame
tk.Button(
frame_main,
image=image_button_1(1),
bd=0,
relief="groove",
compound=tk.CENTER,
bg=bg_color_1,
fg="yellow",
activeforeground="pink",
activebackground=bg_color_1,
font=("TkMenuFont", 12),
cursor="hand2",
text="",
command=lambda: load_frame_insert()
).pack(pady=5)
def load_frame_insert():
print("Hi XYZ")
# ini for app
main_app = tk.Tk()
main_app.title("SRD Loader")
main_app.eval("tk::PlaceWindow . center")
x = main_app.winfo_screenwidth() // 3
y = int(main_app.winfo_screenheight() * 0.1)
main_app.geometry('500x600+' + str(x) + '+' + str(y))
# frame look
frame_main = tk.Frame(main_app, width=500, height=600, bg=bg_color_1)
frame_insert = tk.Frame(main_app, width=500, height=600, bg=bg_color_1)
for frame in (frame_main, frame_insert):
frame.grid(row=0, column=0)
load_main_frame()
main_app.mainloop()
conn.close()
other related topics but doesnt work
youtube tutorials
For the statement command=image_button_1(1), the image returned by image_button_1(1) will be garbage collected because there is no variable referencing it. That is why you get a button without image.
You need to save the reference of the image, for example using an attribute of the button as below:
image = image_button_1(1)
btn = tk.Button(
frame_main,
image=image,
bd=0,
relief="groove",
compound=tk.CENTER,
bg=bg_color_1,
fg="yellow",
activeforeground="pink",
activebackground=bg_color_1,
font=("TkMenuFont", 12),
cursor="hand2",
text="",
command=lambda: load_frame_insert()
)
btn.pack(pady=5)
btn.image = image # save the reference of the image
I removed three libraries.
I removed image_button_1 function
Added image = tk.PhotoImage(file="p1.png")
Added variable for Button
Change 5 to 25 .pack(pady=25)
Removed lambda and brace bracket command=load_frame_insert
Snippet:
import os
import tkinter as tk
running = True
bg_color_1 = "#205E61"
bg_button = "#1B4E51"
bg_button_ac = "#FFD966"
def clear_widgets(frame):
for widget in frame.winfo_children():
widget.destroy()
def load_main_frame():
clear_widgets(frame_insert)
frame_main.tkraise()
frame_main.pack_propagate(False)
# widget frame_main logo
logo_image = tk.PhotoImage(file="p2.png")
logo_widget = tk.Label(frame_main, image=logo_image, bg=bg_color_1)
logo_widget.image = logo_image
logo_widget.pack()
# label on 1st frame
tk.Label(
frame_main,
text=(f"Hi please choose an action"),
bg=bg_button,
fg="white",
font=("TkMenuFont", 12)
).pack(pady=10)
image = tk.PhotoImage(file="p1.png")
# btn code on 1st frame
btn= tk.Button(
frame_main,
image=image,
bd=0,
relief="groove",
compound=tk.CENTER,
bg=bg_color_1,
fg="yellow",
activeforeground="pink",
activebackground=bg_color_1,
font=("TkMenuFont", 12),
cursor="hand2",
text="",
command=load_frame_insert
)
btn.pack(pady=25)
btn.image = image
def load_frame_insert():
print("Hi XYZ")
# ini for app
main_app = tk.Tk()
main_app.title("SRD Loader")
main_app.eval("tk::PlaceWindow . center")
x = main_app.winfo_screenwidth() // 3
y = int(main_app.winfo_screenheight() * 0.1)
main_app.geometry('500x600+' + str(x) + '+' + str(y))
# frame look
frame_main = tk.Frame(main_app, width=500, height=600, bg=bg_color_1)
frame_insert = tk.Frame(main_app, width=500, height=600, bg=bg_color_1)
for frame in (frame_main, frame_insert):
frame.grid(row=0, column=0)
load_main_frame()
main_app.mainloop()
Screenshot:

How can I position an image into a frame in Tkinter and "empty" it everytime I click on a button?

I am creating an EXIF viewer using Tkinter. I need to load an image, which I am already doing, but I can't position it on top of my window into a frame. I used
top_frame = Frame(root)
top_frame.pack(side=TOP)
But I don't know how to position the picture I'm loading into it.
Everytime I load an image it adds it to the view, I'd like to delete the precedent one and add the new one. And this picture must be always inside a precise frame, independently on its size.
This is how I'm visualizing it now:
This is my code:
from tkinter import *
import PIL
from PIL import ImageTk, Image
from tkinter import filedialog
import tkinter as tk
from PIL.ExifTags import TAGS
from exifread.tags import exif
root = tk.Tk()
root.title('Exif Viewer')
root.geometry('500x550')
root.iconbitmap("../icons/exif.png")
def browse_image():
global image_object, image_loaded_label
image_loaded_label = None
root.filename = filedialog.askopenfilename(initialdir="/", title="Select An Image",
filetypes=(("jpeg files", "*.jpeg"), ("png files", "*.png")))
image_object = Image.open(root.filename)
image_loaded = ImageTk.PhotoImage(image_object)
image_loaded_label = Label(image=image_loaded)
image_loaded_label.pack()
image_loaded_label.image = image_loaded
def rotate_image(direction):
global image_object
angle = {"left":90, "right":-90}[direction]
image_object = image_object.rotate(angle)
rotated_tk = ImageTk.PhotoImage(image_object)
image_loaded_label.config(image=rotated_tk)
image_loaded_label.image = rotated_tk #Prevent garbage collection
def get_exif():
global image_object
exif_data = image_object._getexif()
for tag_id in exif_data:
tag_name = TAGS.get(tag_id, tag_id)
value = exif_data.get(tag_id)
print(f"{tag_name:25}: {value}")
top_frame = Frame(root)
top_frame.pack(side=TOP)
bottom_frame = Frame(root)
bottom_frame.pack(side=BOTTOM)
browse_button = Button(bottom_frame, padx=20, pady=5, text="Load image", command=browse_image)
browse_button.grid(row=1, column=0)
browse_button.pack()
rotate_left_button = Button(bottom_frame, padx=10, pady=5, text="Rotate left", command=lambda: rotate_image("left"))
rotate_left_button.pack(side=LEFT)
rotate_right_button = Button(bottom_frame, padx=10, pady=5, text="Rotate right", command=lambda: rotate_image("right"))
rotate_right_button.pack(side=RIGHT)
get_exif = Button(bottom_frame, padx=20, pady=5, text="Get EXIF", command=get_exif)
get_exif.pack(side=TOP)
exit_button = Button(bottom_frame, padx=20, pady=5, text="Exit", command=root.quit)
exit_button.pack()
root.mainloop()

how to display images one after the other in python using tkinter GUI

I have mainly 2 problems in the code:
1) it is showing error "no such directory or file exists" though I have used the same path for an image to another program (though I specified a constant path to only one image) and the images file, this program and the other program, all are in the same working directory
2) it doesn't wait for the wait function, it just executes till 16 and then opens the GUI. I want it to show all the images one by one and change only when I press the 'Next' button
Please suggest any changes in the code which may be required to satisfy the above.
I have Python 3.5.2 in a Windows 10 system.
Thanks in advance
import sys
import tkinter as tk
from PIL import Image,ImageTk,ImageFilter,ImageOps
from msvcrt import getch
def wait():
getch()
return
def classify_obj():
print("In Development")
return
src = "ímages/"
root = tk.Tk()
root.wm_title("Classify Image")
for i in range(1,17):
frame1 = tk.Frame(root, width=500, height=400, bd=2)
frame1.grid(row=1, column=0)
cv1 = tk.Canvas(frame1, height=390, width=490, background="white", bd=1, relief=tk.RAISED)
cv1.grid(row=1,column=0)
im = Image.open(src+str(i)+".jpg")
if (490-im.size[0])<(390-im.size[1]):
width = 490
height = width*im.size[1]/im.size[0]
else:
height = 390
width = height*im.size[0]/im.size[1]
im.thumbnail((width, height), Image.ANTIALIAS)
photo = ImageTk.PhotoImage(im)
cv1.create_image(0, 0, image=photo, anchor='nw')
claButton = tk.Button(master=root, text='Classify', height=2, width=10, command=classify_obj)
claButton.grid(row=0, column=1, padx=2, pady=2)
frame2 = tk.Frame(root, width=500, height=400, bd=1)
frame2.grid(row=1, column=1)
cv2 = tk.Canvas(frame2, height=390, width=490, bd=2, relief=tk.SUNKEN)
cv2.grid(row=1,column=1)
broButton = tk.Button(master=root, text='Next', height=2, width=8, command=wait)
broButton.grid(row=0, column=0, padx=2, pady=2)
print(i)
tk.mainloop()
So on of the big problems with getting the next image the way you are trying to do it is the for loop. What is happening is you have told python the check everything in that loop and perform those functions.
I think one better way would be to first create this program as a class. This way we can avoid calling global variables anywhere in the program. Then inside said class on __init__ we create a list of every photo image inside of our image folder. (Note: I have only tested this with .jpg images). Now that we have a list of all the file names we can then use that list to get a count of how many image files we are working with. With this count we can create a counter that lets us select the next index in the list thus selecting the next image in said list.
By creating all our variables as an attribute of the class we can interact with those attributes without having to declare them as global.
Take the following example. Just change the src variable to your file path.
remember to use . in your file path if your folder is inside your main python workspace. Example: I have a folder called TestImages inside the same directory as my main.py so I can make this variable: src = "./TestImages/".
Take a look at the code below:
import tkinter as tk
from PIL import Image,ImageTk
import os
class ImageClassifyer(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.root = parent
self.root.wm_title("Classify Image")
src = "./TestImages/"
self.list_images = []
for d in os.listdir(src):
self.list_images.append(d)
self.frame1 = tk.Frame(self.root, width=500, height=400, bd=2)
self.frame1.grid(row=1, column=0)
self.frame2 = tk.Frame(self.root, width=500, height=400, bd=1)
self.frame2.grid(row=1, column=1)
self.cv1 = tk.Canvas(self.frame1, height=390, width=490, background="white", bd=1, relief=tk.RAISED)
self.cv1.grid(row=1,column=0)
self.cv2 = tk.Canvas(self.frame2, height=390, width=490, bd=2, relief=tk.SUNKEN)
self.cv2.grid(row=1,column=0)
claButton = tk.Button(self.root, text='Classify', height=2, width=10, command=self.classify_obj)
claButton.grid(row=0, column=1, padx=2, pady=2)
broButton = tk.Button(self.root, text='Next', height=2, width=8, command = self.next_image)
broButton.grid(row=0, column=0, padx=2, pady=2)
self.counter = 0
self.max_count = len(self.list_images)-1
self.next_image()
def classify_obj(self):
print("In Development")
def next_image(self):
if self.counter > self.max_count:
print("No more images")
else:
im = Image.open("{}{}".format("./TestImages/", self.list_images[self.counter]))
if (490-im.size[0])<(390-im.size[1]):
width = 490
height = width*im.size[1]/im.size[0]
self.next_step(height, width)
else:
height = 390
width = height*im.size[0]/im.size[1]
self.next_step(height, width)
def next_step(self, height, width):
self.im = Image.open("{}{}".format("./TestImages/", self.list_images[self.counter]))
self.im.thumbnail((width, height), Image.ANTIALIAS)
self.root.photo = ImageTk.PhotoImage(self.im)
self.photo = ImageTk.PhotoImage(self.im)
if self.counter == 0:
self.cv1.create_image(0, 0, anchor = 'nw', image = self.photo)
else:
self.im.thumbnail((width, height), Image.ANTIALIAS)
self.cv1.delete("all")
self.cv1.create_image(0, 0, anchor = 'nw', image = self.photo)
self.counter += 1
if __name__ == "__main__":
root = tk.Tk()
MyApp = ImageClassifyer(root)
tk.mainloop()
There are lots of issues with the current code. I tried to make it work with as little change as possible. The fundamental problem was that the button binding to wait() goes against the principle of having a GUI. So in short, here is a framework from which to get started...
import tkinter as tk
from PIL import Image,ImageTk,ImageFilter,ImageOps
from msvcrt import getch
src = 'images/'
i = 1
def showImage():
global i
# You need to do file exists error checking here.
try:
im = Image.open(src+str(i)+".jpg")
except:
print("No image file named", src+str(i)+".jpg")
return
if (490-im.size[0])<(390-im.size[1]):
width = 490
height = width*im.size[1]/im.size[0]
else:
height = 390
width = height*im.size[0]/im.size[1]
im.thumbnail((width, height), Image.ANTIALIAS)
photo = ImageTk.PhotoImage(im)
label.configure(image=photo)
label.image = photo
i += 1
return
def classify_obj():
print("In Development")
return
root = tk.Tk()
root.wm_title("Classify Image")
frame1 = tk.Frame(root, width=500, height=400, bd=2)
frame1.grid(row=1, column=0)
cv1 = tk.Canvas(frame1, height=390, width=490, background="white", bd=1, relief=tk.RAISED)
label = tk.Label(cv1)
cv1.create_window(0, 0, anchor='nw', window=label)
cv1.grid(row=1,column=0)
claButton = tk.Button(master=root, text='Classify', height=2, width=10, command=classify_obj)
claButton.grid(row=0, column=1, padx=2, pady=2)
frame2 = tk.Frame(root, width=500, height=400, bd=1)
frame2.grid(row=1, column=1)
cv2 = tk.Canvas(frame2, height=390, width=490, bd=2, relief=tk.SUNKEN)
cv2.grid(row=1,column=1)
broButton = tk.Button(master=root, text='Next', height=2, width=8, command=showImage)
broButton.grid(row=0, column=0, padx=2, pady=2)
showImage()
tk.mainloop()

Changing Image with Button Click with Python Tkinter [duplicate]

This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 5 years ago.
I want to display 2 different images when a button is pressed. I have two images, and corresponding 2 buttons. I'm using the panel's configure function to try to change the image but to no avail. How would I accomplish this? Thank you!
import Tkinter as tk
from PIL import ImageTk, Image
def next(panel):
path = "2.jpg"
img = ImageTk.PhotoImage(Image.open(path))
panel.configure(image=img)
panel.image = img # keep a reference!
def prev(panel):
path = "1.jpg"
img = ImageTk.PhotoImage(Image.open(path))
panel.configure(image=img)
panel.image = img # keep a reference!
#Create main window
window = tk.Tk()
#divide window into two sections. One for image. One for buttons
top = tk.Frame(window)
top.pack(side="top")
bottom = tk.Frame(window)
bottom.pack(side="bottom")
#place image
path = "1.jpg"
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(window, image = img)
panel.image = img # keep a reference!
panel.pack(side = "top", fill = "both", expand = "yes")
#place buttons
prev_button = tk.Button(window, text="Previous", width=10, height=2, command=prev(panel))
prev_button.pack(in_=bottom, side="left")
next_button = tk.Button(window, text="Next", width=10, height=2, command=next(panel))
next_button.pack(in_=bottom, side="right")
#Start the GUI
window.mainloop()
To pass arguments to a button callback command, you need the lambda keyword, else the functions will be called at the time of button creation.
#place buttons
prev_button = tk.Button(window, text="Previous", width=10, height=2, command=lambda: prev(panel))
prev_button.pack(in_=bottom, side="left")
next_button = tk.Button(window, text="Next", width=10, height=2, command=lambda: next(panel))
next_button.pack(in_=bottom, side="right")

Displaying .jpg image when button is clicked in Tkinter?

This seems like a pretty straightforward question, but i am having trouble displaying a jpg image when a button is clicked. Here is my code (without the button code for the sake of time):
from tkinter import *
#screen stuff here
canvas = Canvas(app)
canvas.grid(row = 0,column = 0)
photo = PhotoImage(file = "test.jpg")
canvas.create_image(0,0, image = photo)
def show_image():
global canvas
global photo
canvas.create_image(0,0, image = photo)
#button that calls the function down here
Thanks!
This works with Python2:
import Tkinter as tk
import ImageTk
def show_image():
x = canvas.create_image(125, 125, image=tk_img)
while True:
print('show')
canvas.itemconfigure(x, state=tk.NORMAL)
button.configure(text = 'Hide')
yield
print('hide')
canvas.itemconfigure(x, state=tk.HIDDEN)
button.configure(text = 'Show')
yield
root = tk.Tk()
canvas = tk.Canvas(root, width=250, height=250)
canvas.grid(row=0, column=0)
tk_img = ImageTk.PhotoImage(file='image.png')
button = tk.Button(
root, text="Show", command=show_image().next, anchor='w',
width=10, activebackground="#33B5E5")
button.grid(row=1, column=0)
root.mainloop()
In Python3, PhotoImage can open GIF, PPM/PGM images. To open other formats, you may need to install Pillow (a fork of the PIL project for Python3).

Categories

Resources