How to change image and fit inside label? - python

view = Tk()
view.title("Title")
view.geometry('600x600')
view.attributes("-fullscreen",True)
def resize_image(event):
new_width = event.width
new_height = event.height
image = copy_of_image.resize((new_width, new_height))
photo = ImageTk.PhotoImage(image)
label.config(image = photo)
label.image = photo
image = Image.open('add.png')
copy_of_image = image.copy()
photo = ImageTk.PhotoImage(image)
label = ttk.Label(view, image = photo)
label.bind('<Configure>', resize_image)
label.pack(fill=BOTH, expand = YES)
command="pwd"
def changePicture():
print("I change picture")
image2 = Image.open('add.png')
copy_of_image = image2.copy()
photo = ImageTk.PhotoImage(image2)
label = ttk.Label(view, image = photo)
label.image=image2
label.pack()
It just stands and can't change picture. I got other codes to "add.png" image. Just window stays still and no change. Thanks foryour help guys in advance.

change the line:
label.pack(fill=BOTH, expand = YES)
to
label.pack()

Related

Unable To Save Tkinter PhotoImage

I am trying to convert colour images into Grayscale images and then save the output.
The code works fine as expected (I am able to import images and perfrom grayscale operations on it)
However, I am unable to save the tk PhotoImage, hence, getting the error
'PhotoImage' object has no attribute 'save'
This is the code
from tkinter import *
from PIL import Image
from PIL import ImageTk
from tkinter import filedialog
import cv2
gray = None
def select_image():
global left_side, right_side
f_types = [
("Jpg Files", "*.jpg"),
("PNG Files", "*.png"),
] # type of files to select
path = filedialog.askopenfilename(multiple=False, filetypes=f_types)
# ensure a file path was selected
if len(path) > 0:
image = cv2.imread(path)
print(path)
global gray
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# convert the images to PIL format...
image = Image.fromarray(image)
gray = Image.fromarray(gray)
# ...and then to ImageTk format
image = ImageTk.PhotoImage(image)
gray = ImageTk.PhotoImage(gray)
# if the sections are None, initialize them
if left_side is None or right_side is None:
# the first section will store our original image
left_side = Label(image=image)
left_side.image = image
left_side.pack(side="left", padx=10, pady=10)
# while the second section will store the edge map
right_side = Label(image=gray)
right_side.image = gray
right_side.pack(side="right", padx=10, pady=10)
# otherwise, update the image sections
else:
# update the sections
left_side.configure(image=image)
right_side.configure(image=gray)
left_side.image = image
right_side.image = gray
# save bw
def savefile():
filename = filedialog.asksaveasfile(mode="w", defaultextension=".jpg")
if not filename:
return
gray.save(filename)
# print(gray)
window = Tk()
window.geometry("1080x720")
window.title("Colored Image To Black & White")
icon = PhotoImage(file="logo1.png")
window.iconphoto(True, icon)
image = PhotoImage(file="logo1.png")
intro = Label(
window,
text="This program converts Colored Images into Grayscale Images",
font=("Comic Sans", 20,),
fg="#FF6405",
bg="black",
compound="right",
)
intro.pack()
left_side = None
right_side = None
btn = Button(
window,
text="select image",
command=select_image,
font=("Comic Sans", 30),
fg="red",
bg="black",
)
btn1 = Button(
window,
text="select image",
command=savefile,
font=("Comic Sans", 30),
fg="red",
bg="black",
)
img = PhotoImage(file="select.png")
btn.config(image=img)
btn.pack(side="left", fill="both", expand="no", padx="10", pady="10")
img2 = PhotoImage(file="save.png")
btn1.config(image=img2)
btn1.pack(side="right", fill="both", expand="no", padx="10", pady="10")
window.config(background="#FF6405")
# window.resizable(False, False)
window.mainloop()

Tkinter will only display the first photo I select via filedialog.askopenfilename

I have a program that allows the user to select an image from their PC and then displays it. The problem is that it only works once. The first photo is displayed but if I select/open another, I would think that this photo would then appear on top of the original but it doesn't.
Any idea why?
root = tk.Tk()
root.geometry("500x500")
root.title('Color Comparer')
picture_chooser_btn = tk.Button(master=root, text='Select Image', command= lambda: open_image())
picture_chooser_btn.pack()
base_color_picker_btn = tk.Button(master=root, text='Choose Base Color', command= lambda: selectBaseColor())
base_color_picker_btn.pack()
canvas = Canvas(root, width=80, height=50, bg="#F8F9F9")
base_color_rect = canvas.create_rectangle(0, 0, 85, 85, fill="red")
canvas_label = canvas.create_text((42, 20), text="Base Color")
canvas.pack()
label = tk.Label(root, anchor="w")
label.pack(side="top", fill="x")
root.bind('<ButtonPress-1>', on_click)
root.mainloop()
The function used to grab the photo from PC:
def open_image():
global image_selected
path=filedialog.askopenfilename(filetypes=[("Image File",'.jpg .png .jpeg')])
im = Image.open(path)
im = im.resize((400, 400), Image.ANTIALIAS)
tkimage = ImageTk.PhotoImage(im)
myvar=Label(root,image = tkimage)
myvar.image = tkimage
myvar.pack()
myvar.lift()
label.configure(text="you selected an image")
print("you selected an image")
print(str(tkimage))
image_selected = True
You need to destroy the old label widget containing the previous image before you can display a new one.
I made some minor modifications to your function that allows the code to work as you described
myvar = None
def open_image():
global myvar
if myvar is not None:
myvar.destroy()
path=filedialog.askopenfilename(filetypes=[("Image File",'.jpg .png .jpeg')])
im = Image.open(path)
im = im.resize((400, 400), Image.ANTIALIAS)
tkimage = ImageTk.PhotoImage(im)
myvar=Label(root,image = tkimage)
myvar.image = tkimage
myvar.pack()
myvar.lift()
label.configure(text="you selected an image")
print("you selected an image")
print(str(tkimage))

Fit canvas to windows

I have an image (1200 x 2064) from a videp:
I want to display it with Tkinter. So I did that:
cap = cv2.VideoCapture(path_video)
cap.set(1, 1)
ret, frame = cap.read()
self._root = tk.Tk()
self._root.minsize(height=frame.shape[0], width=frame.shape[1] + 150)
self._root.title("Image")
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = Image.fromarray(image)
image = ImageTk.PhotoImage(image)
canvas_1 = tk.Canvas( self._root, height=frame.shape[0], width=150)
canvas_1.grid(row=0, column=0)
canvas_1.create_text(10, 10, anchor='nw', text='Pixel: ')
canvas_2 = tk.Canvas( self._root, height=frame.shape[0], width=frame.shape[1])
canvas_2.grid(row=0, column=1)
canvas_2.image = image
canvas_2.create_image(0, 0, anchor='nw', image=image)
self._root.mainloop()
The image is cropped at the bottom (or my laptop screen is too small). I want to have the whole image in the canvas_2. How can I do that ?
Here is the real image

Can you rescale a PhotoImage in Python Tkinter?

In my program, I have two buttons. button1 calls a function (bt1) which displays an image in the window and then deletes both buttons. button2 calls a function(bt2) I would like this button to display the same image as button1 but by half the scale factor. I am thinking something like this:
scale_half_img = PhotoImage(file = 'Image.png', scale = 0.5)
Of course, this doesn't work but this is the sort of thing I am looking for.
Full code:
from tkinter import *
window = Tk()
def bt1():
img = PhotoImage(file = 'Image.png')
imglbl = Label(window, image = img, anchor = 'nw')
imglbl.place(x = 0, y = 0, width = 865, height = 800)
button1.destroy()
button2.destroy()
def bt2():
# display scaled down image
button1.destroy()
button2.destroy()
button1 = Button(window, text = 'Display Image', command = bt1)
button1.place(x = 10, y = 10, width = 200, height = 30)
button2 = Button (window, text = 'Display Rescaled Image', command = bt2)
button2.place(x = 10, y = 50, width = 200, height = 30)
window.mainloop()
Use PIL.Image to resize an image in tkinter. You can do it as follows:
from PIL import Image, ImageTk
img = Image.open('<Path to Image>')
img = img.resize((img.size[0]/2, img.size[1]/2), Image.ANTIALIAS)
resized_image = ImageTk.Photoimage(img) # use this

Dynamically changing images connected to the item in listbox

I would like to dynamically display image of selected item in listbox.
The name of the image store in folder is exactly like item with index [0] from my tuple in listbox
list1= Listbox(ViewFrame, height=15, width=75)
files = glob.glob('img\\*.jpg')
ImageFrame = LabelFrame(page1, text="Podgląd i parametry")
ImageFrame.grid(row=6, column=6, pady=10, padx=5)
path = files[list1.curselection()[0]]
img = ImageTk.PhotoImage(Image.open(path))
label = Label(ImageFrame)
label.image = img
label.configure(image=img)
Error:
path = files[list1.curselection()[0]]
IndexError: tuple index out of range
It seems to me that before I open the app nothing is selected, but I do not know how to fix it.
check is something is selected before load images.
when create the listbox add
list1.bind("<<ListboxSelect>>", on_item_selected)
then add the function
def (on_item_selected):
path = files[list1.curselection()[0]]
img = ImageTk.PhotoImage(Image.open(path))
label = Label(ImageFrame)
label.image = img
label.configure(image=img)
on open....
if list1.curselection():
path = files[list1.curselection()[0]]
img = ImageTk.PhotoImage(Image.open(path))
label = Label(ImageFrame)
label.image = img
label.configure(image=img)
Here's runnable code, but it's merely a more complete version of #1966bc's answer which I created because you have in your question isn't a MCVE:
import glob
from tkinter import *
from PIL import Image, ImageTk
def on_item_selected(event):
path = files[list1.curselection()[0]]
img = ImageTk.PhotoImage(Image.open(path))
label.image = img
label.configure(image=img)
root = Tk()
page1 = Frame(root)
page1.grid(row=0, column=0)
ViewFrame = Frame(page1)
ViewFrame.grid(row=0, column=0)
files = glob.glob('*.jpg')[:10] # Limit to first 10 for development.
listvar = StringVar(value=files)
list1= Listbox(ViewFrame, height=15, width=75, listvariable=listvar)
list1.grid()
ImageFrame = LabelFrame(page1, text="Podgląd i parametry")
ImageFrame.grid(row=6, column=6, pady=10, padx=5)
label = Label(ImageFrame) # Create placeholder.
label.grid()
list1.bind("<<ListboxSelect>>", on_item_selected)
root.mainloop()

Categories