Reputation: 442
I have several images that I need to display in a Tkinter window (I'll probably use a canvas to display them - possibly a label). These images will take up about a third of the screen. I need the image-screen ratio to be consistent when the user uses different sized monitors.
So say the user uses a tiny monitor, the images need to take up the same photo-screen ration on the small screen, to when the user uses a massive 4K monitor.
Will Tkinter automatically do this for me? Or will I have to implement it myself - if so, is that even possible?
I don't have any code because I have no idea where to start. I thought that I could use PIL or pillow maybe, but I'm fairly new to them.
Any help would be appreciated, thanks :)
Upvotes: 1
Views: 4426
Reputation: 1
Yes, you can do it like this:
import PIL.Image
import tkinter as tk
from PIL import ImageTk
from tkinter.filedialog import askopenfilename
class CanvasImage(tk.Canvas):
def __init__(self, master: tk.Tk, **kwargs):
super().__init__(master, **kwargs)
self.source_image = None
self.image_id = None
self.image = None
self.width, self.height = 0, 0
self.center_x, self.center_y = 0, 0
self.bind('<Configure>', self.update_values)
def update_values(self, *_) -> None:
self.width = self.winfo_width()
self.height = self.winfo_height()
self.center_x = self.width//2
self.center_y = self.height//2
if self.image is None: return
self.delete_previous_image()
self.resize_image()
self.paste_image()
def delete_previous_image(self) -> None:
if self.image is None: return
self.delete(self.image_id)
self.image = self.image_id = None
def resize_image(self) -> None:
image_width, image_height = self.source_image.size
width_ratio = self.width / image_width
height_ratio = self.height / image_height
ratio = min(width_ratio, height_ratio)
new_width = int(image_width * ratio)
new_height = int(image_height * ratio)
scaled_image = self.source_image.resize((new_width, new_height))
self.image = ImageTk.PhotoImage(scaled_image)
def paste_image(self) -> None:
self.image_id = self.create_image(self.center_x, self.center_y, image=self.image)
def open_image(self) -> None:
if not (filename := askopenfilename()): return
self.delete_previous_image()
self.source_image = PIL.Image.open(filename)
self.image = ImageTk.PhotoImage(self.source_image)
self.resize_image()
self.paste_image()
class Window(tk.Tk):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.canvas = CanvasImage(self, relief='sunken', bd=2)
tk.Button(self, text='Abrir imagen', comman=self.canvas.open_image).pack()
self.canvas.pack(expand=True, fill='both', padx=10, pady=10)
if __name__ == '__main__':
window = Window()
window.mainloop()
Upvotes: 0
Reputation: 612
1) You need to get current screen resolution: How do I get monitor resolution in Python?
2) Then you need to adjust size of your image (How do I resize an image using PIL and maintain its aspect ratio?) and/or your window (https://yagisanatode.com/2018/02/23/how-do-i-change-the-size-and-position-of-the-main-window-in-tkinter-and-python-3/)
So the code should look like that:
from win32api import GetSystemMetrics
from Tkinter import Tk
screen_width, screen_height = GetSystemMetrics(0), GetSystemMetrics(1)
root = Tk() # this is your window
root.geometry("{}x{}".format(screen_width//2, screen_height//2)) # set size of you window here is example for 1/2 screen height and width
img = Image.open("picture_name.png", "r") # replace with picture path
width, height = screen_width//4, screen_height//4 # determine widght and height basing on screen_width, screen_height
img.resize((width, height), Image.ANTIALIAS)
# todo: create more Tkinter objects and pack them into root
root.mainloop()
This should probably solve your problem. Regarding Tkinter usage, there are a lot of tutorials, example: http://effbot.org/tkinterbook/
Upvotes: 1