Hi, please find the problem and code in the below link:
Continuing the discussion from Why no image is opened using this function?:
Hi, please find the problem and code in the below link:
Continuing the discussion from Why no image is opened using this function?:
Hey Abbas from the previous discussion am getting that you are saying you can open but the image is resized… nywy with filedialog the location of the image is relative since images will be in different directories while a fixed path is fixed literally like the path of all the images is absolute…
I was checking and I got this that Note: Location of image should be relative only if the image is in the same directory as the Python program, otherwise absolute (full) path of the image should be provided.
that note is from https://www.geeksforgeeks.org/python-pillow-a-fork-of-pil/
Now just a thought will cob=nverting a relative path absolute solve it? once a user selects the location of an image/file can you can you now convert it to an absolute path before opening the intended file
Thank you for your consideration. Indeed, the problem is that result of running the first code is different from running the second version. I expect that the both versions resize the image; however, the image is resized only if it has been opened using filedialog.askdirectory (version 2):
First version:
import os
import tkinter as tk
from tkinter import filedialog, ttk
from PIL import Image, ImageTk
class Manual:
def __init__(self, root):
self.root = root
self.root.title("Manual")
window_width = 800
window_height = 600
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
x = int((screen_width / 2) - (window_width / 2))
y = int((screen_height / 2) - (window_height / 2))
self.root.geometry(f"{window_width}x{window_height}+{x}+{y}")
self.canvas = None
self.folder_path = ""
self.image_files = []
self.current_image = 0
self.total_images = 0
self.image = None
# Option 1:
self.in_path = r"C:\Users\Markazi.co\Desktop\input 3"
self.canvas_frame = tk.Frame(self.root)
self.canvas_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
self.canvas_scrollbar_x = ttk.Scrollbar(self.canvas_frame, orient=tk.HORIZONTAL)
self.canvas_scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
self.canvas_scrollbar_y = ttk.Scrollbar(self.canvas_frame)
self.canvas_scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
self.canvas = tk.Canvas(self.canvas_frame, bg='white', xscrollcommand=self.canvas_scrollbar_x.set,
yscrollcommand=self.canvas_scrollbar_y.set)
self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.canvas_scrollbar_x.config(command=self.canvas.xview)
self.canvas_scrollbar_y.config(command=self.canvas.yview)
def open_folder(self):
# Option 2:
#self.in_path = filedialog.askdirectory()
if self.in_path:
self.image_files = sorted([f for f in os.listdir(self.in_path) if f.lower().endswith('.jpg')])
self.total_images = len(self.image_files)
self.open_image()
def open_image(self):
if self.current_image < self.total_images:
image_file = self.image_files[self.current_image]
self.image = Image.open(os.path.join(self.in_path, image_file))
self.show_image(image_file, self.current_image + 1, self.total_images)
else:
self.canvas.delete("all")
self.canvas.pack_forget() # Hide the canvas
def show_image(self, image_file, current_image, total_images):
if self.image:
width, height = self.calculate_image_size()
self.image = self.image.resize((width, height), Image.LANCZOS)
self.tk_image = ImageTk.PhotoImage(self.image)
self.canvas.config(scrollregion=(0, 0, width, height))
self.canvas.delete("all")
self.canvas.create_image(0, 0, anchor=tk.NW, image=self.tk_image)
def calculate_image_size(self):
if self.image:
window_width = self.root.winfo_width()
window_height = self.root.winfo_height()
border = 20
max_width = window_width - (2 * border)
max_height = window_height - (2 * border)
image_ratio = self.image.width / self.image.height
window_ratio = max_width / max_height
if image_ratio > window_ratio:
width = max_width
height = int(max_width / image_ratio)
else:
width = int(max_height * image_ratio)
height = max_height
return width, height
root = tk.Tk()
root.eval('tk::PlaceWindow . center')
app = Manual(root)
app.open_folder() # Call open_folder() to open the folder only once
root.mainloop()
Second version (using filedialog.askdirectory()):
import os
import tkinter as tk
from tkinter import filedialog, ttk
from PIL import Image, ImageTk
class Manual:
def __init__(self, root):
self.root = root
self.root.title("Manual")
window_width = 800
window_height = 600
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
x = int((screen_width / 2) - (window_width / 2))
y = int((screen_height / 2) - (window_height / 2))
self.root.geometry(f"{window_width}x{window_height}+{x}+{y}")
self.canvas = None
self.folder_path = ""
self.image_files = []
self.current_image = 0
self.total_images = 0
self.image = None
# Option 1:
#self.in_path = r"C:\Users\Markazi.co\Desktop\input 3"
self.canvas_frame = tk.Frame(self.root)
self.canvas_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
self.canvas_scrollbar_x = ttk.Scrollbar(self.canvas_frame, orient=tk.HORIZONTAL)
self.canvas_scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
self.canvas_scrollbar_y = ttk.Scrollbar(self.canvas_frame)
self.canvas_scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
self.canvas = tk.Canvas(self.canvas_frame, bg='white', xscrollcommand=self.canvas_scrollbar_x.set,
yscrollcommand=self.canvas_scrollbar_y.set)
self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.canvas_scrollbar_x.config(command=self.canvas.xview)
self.canvas_scrollbar_y.config(command=self.canvas.yview)
def open_folder(self):
# Option 2:
self.in_path = filedialog.askdirectory()
if self.in_path:
self.image_files = sorted([f for f in os.listdir(self.in_path) if f.lower().endswith('.jpg')])
self.total_images = len(self.image_files)
self.open_image()
def open_image(self):
if self.current_image < self.total_images:
image_file = self.image_files[self.current_image]
self.image = Image.open(os.path.join(self.in_path, image_file))
self.show_image(image_file, self.current_image + 1, self.total_images)
else:
self.canvas.delete("all")
self.canvas.pack_forget() # Hide the canvas
def show_image(self, image_file, current_image, total_images):
if self.image:
width, height = self.calculate_image_size()
self.image = self.image.resize((width, height), Image.LANCZOS)
self.tk_image = ImageTk.PhotoImage(self.image)
self.canvas.config(scrollregion=(0, 0, width, height))
self.canvas.delete("all")
self.canvas.create_image(0, 0, anchor=tk.NW, image=self.tk_image)
def calculate_image_size(self):
if self.image:
window_width = self.root.winfo_width()
window_height = self.root.winfo_height()
border = 20
max_width = window_width - (2 * border)
max_height = window_height - (2 * border)
image_ratio = self.image.width / self.image.height
window_ratio = max_width / max_height
if image_ratio > window_ratio:
width = max_width
height = int(max_width / image_ratio)
else:
width = int(max_height * image_ratio)
height = max_height
return width, height
root = tk.Tk()
root.eval('tk::PlaceWindow . center')
app = Manual(root)
app.open_folder() # Call open_folder() to open the folder only once
root.mainloop()
As suggested by ChatGPT 3.5, adding “root.update()” at the end of the code, solved the problem:
...
root = tk.Tk()
root.eval('tk::PlaceWindow . center')
app = Manual(root)
root.update() # Update the window to ensure the size is final
app.open_folder() # Call open_folder() to open the folder only once
root.mainloop()