Fit canvas to windows - python

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

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()

Trying to add bmp image to ScrolledText widget and it says it does not exist (Tkinter)

I'm trying to add a program icon I got as a bmp image to a ScrolledText widget. I'm getting this error:
_tkinter.TclError: image "<PIL.BmpImagePlugin.BmpImageFile image mode=RGB size=32x32 at 0x19B2FA18EB0>" doesn't exist
Here's the relevant code:
def get_icon(exe):
ico_x = win32api.GetSystemMetrics(win32con.SM_CXICON)
ico_y = win32api.GetSystemMetrics(win32con.SM_CYICON)
large, small = win32gui.ExtractIconEx(exe, 0)
win32gui.DestroyIcon(small[0])
hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
hbmp = win32ui.CreateBitmap()
hbmp.CreateCompatibleBitmap(hdc, ico_x, ico_y)
hdc = hdc.CreateCompatibleDC()
hdc.SelectObject(hbmp)
hdc.DrawIcon((0, 0), large[0])
hbmp.SaveBitmapFile(hdc, 'icon.bmp')
img = Image.open("icon.bmp")
return img
text_area = ScrolledText(root,
width = 40,
height = 40,
font = ("Times New Roman",
25))
img = get_icon("C:\Program Files\BraveSoftware\Brave-Browser\Application\Brave.exe")
text_area.image_create("current", padx=5, pady=5, image=ImageTk.PhotoImage(img))
text_area.place(relx=0.2, rely=0.1, relwidth=0.5, relheight=0.5, anchor='s')
Any ideas?

OpenCV w/ Tkinter : Lag & window problems

I recently started using opencv with tkinter, and I started to have some problems that I can't seem to fix by myself...
The following code is supposed to play a video file while being able to choose which sub-directory you want to sort the file in. The problems I started to have is that the number of frames per seconds seems to act weird, since some clip I play seems "lagging", or don't have the right fps.
Secondly, the code seems really messy, and thus buttons "disappear" after clicking on one for a moment.
And finally, I tried to do something so the buttons get as big as possible to fill the x axis on the bottom of the window, while the main frame, with the video playing, stays the same same size (so the video is supposed to stay in the middle, adapting his height and width to the frame size without changing the ratio) but that doesn't seems to work too.
Any help will be appreciated
PS: I am using Python 3.8 with openCV 4.1.2
Here is the code :
from tkinter import Tk, Button, Label, Frame
import os
import shutil
import cv2
from PIL import Image, ImageTk
x = 0
path = "path/to/folder"
def nbr():
global x
x += 1
text.config(text=files[x])
class ButtonX (Button):
def __init__ (self, *args, folder="", **kwargs):
super().__init__(*args, **kwargs)
self.folder = folder
self.config(command=self.moveTo)
def moveTo(self):
global x
global cap
global width
if cap.isOpened():
cap.release()
shutil.move(path + files[x], path + self.folder + "/" +files[x])
print(files[x] + " moved to " + self.folder)
nbr()
cap = cv2.VideoCapture(path+files[x])
ret, frame = cap.read()
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)*(height/cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
folders = [dI for dI in os.listdir(path) if os.path.isdir(os.path.join(path,dI))]
allfiles = os.listdir(path)
files = [ fname for fname in allfiles if fname.endswith('.webm')]
files.sort(key=len)
print(folders)
window = Tk()
window.resizable(0, 0)
window.geometry("1600x908")
back = Frame(window)
back.grid(row=1, column=1)
window.grid_rowconfigure(0, weight=1)
window.grid_rowconfigure(2, weight=1)
window.grid_columnconfigure(0, weight=1)
window.grid_columnconfigure(2, weight=1)
player = Frame(back)
player.grid(row = 0, column=0)
buttouns = Frame(back)
buttouns.grid(row = 1, column=0)
text = Label(player)
text.grid(row=0, columnspan=4, sticky='w,e,n,s', padx=5, pady=50)
cap = cv2.VideoCapture(path+files[x])
fps = cap.get(cv2.CAP_PROP_FPS)
cap.set(cv2.CAP_PROP_FPS, fps)
print(fps)
height = 600
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)*(height/cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
def show_frame():
global cap
global width
cap.set(cv2.CAP_PROP_FPS, fps)
ret, frame = cap.read()
if frame is None:
cap = cv2.VideoCapture(path+files[x])
ret, frame = cap.read()
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image).resize((width, height))
imgtk = ImageTk.PhotoImage(image = img)
text.imgtk = imgtk
text.configure(image=imgtk)
text.after(3, show_frame)
buttons = []
z = 1
y = 0
for i in range(len(folders)):
new_button = ButtonX(buttouns,text=folders[i], width=20, height=2, folder=folders[i])
buttons.append(new_button)
buttons[i].grid(row=z, column=y, sticky='w,e,n,s', padx=5, pady=5)
y += 1
if y == 4:
y = 0
z += 1
def deleted():
global cap
global width
print("deleted " + files[x])
if cap.isOpened():
cap.release()
shutil.move(path + files[x], "path/to/deleted" + files[x])
nbr()
cap = cv2.VideoCapture(path+files[x])
ret, frame = cap.read()
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)*(height/cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
def skipped():
global cap
global width
print(files[x] + " skipped")
if cap.isOpened():
cap.release()
nbr()
cap = cv2.VideoCapture(path+files[x])
ret, frame = cap.read()
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)*(height/cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
delete= Button(buttouns,text="Delete", width=20, height=2, command=deleted, foreground="red")
delete.grid(row=z+1,column=2, columnspan=2, sticky='w,e,n,s', padx=5, pady=5)
skip= Button(buttouns,text="Skip", width=20, height=2, command=skipped)
skip.grid(row=z+1, columnspan=2, sticky='w,e,n,s', padx=5, pady=5)
show_frame()
window.mainloop()

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

How to change image and fit inside label?

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()

Categories