Display Image in Python
artydev

artydev @artydev

Joined:
Jul 17, 2019

Display Image in Python

Publish Date: Jun 4
0 0

Here is a script allowing to display images in a resizable window, mantaining aspect ratio :

import tkinter as tk
from tkinter import ttk # For themed widgets (optional)
from PIL import Image, ImageTk
import os

class ImageApp:
    def __init__(self, master, image_path):
        self.master = master
        master.title("C# Image Viewer")

        self.image_path = image_path
        self.original_image = None
        self.tk_image = None
        self.canvas_item = None # To hold the image on the canvas

        # Check if image exists and load it
        if not os.path.exists(self.image_path):
            print(f"Error: Image file not found at {self.image_path}")
            master.destroy() # Close the window if image not found
            return

        try:
            self.original_image = Image.open(self.image_path)
            print(f"Image successfully opened: {self.original_image.format}, {self.original_image.size}, {self.original_image.mode}")
        except Exception as e:
            print(f"Error loading image with Pillow: {e}")
            master.destroy()
            return

        # Create a Canvas widget to display the image
        self.canvas = tk.Canvas(master, bg="black", highlightthickness=0)
        self.canvas.pack(fill=tk.BOTH, expand=True)

        # Bind the <Configure> event to the resize_image method
        # This event fires when the widget (canvas in this case) changes size
        self.canvas.bind("<Configure>", self.resize_image)

        # Initial display of the image
        self.display_initial_image()

    def display_initial_image(self):
        if self.original_image:
            # Get initial canvas size or set it to image size for first open
            # This is a bit tricky as canvas size might be 1x1 initially.
            # We'll rely on the <Configure> event to do the actual initial sizing.

            # For the very first display, let's just make sure something is there.
            # The <Configure> event will immediately follow and correctly size it.
            temp_image = self.original_image.copy() # Avoid modifying original
            # If the image is very large, you might want to scale it down for initial display
            # otherwise, the window might open off-screen if the screen is too small.
            # However, for maintaining aspect ratio, the resize_image method handles it.

            self.tk_image = ImageTk.PhotoImage(temp_image)
            self.canvas_item = self.canvas.create_image(0, 0, anchor=tk.NW, image=self.tk_image)

            # Set initial window size to match image size (optional, can be skipped
            # if you prefer the user to manually stretch to fit)
            self.master.geometry(f"{self.original_image.width}x{self.original_image.height}")


    def resize_image(self, event):
        if self.original_image:
            # Get current canvas dimensions
            canvas_width = event.width
            canvas_height = event.height

            # Calculate aspect ratio
            original_width, original_height = self.original_image.size
            original_aspect_ratio = original_width / original_height

            # Determine new dimensions to fit within canvas while maintaining aspect ratio
            # Option 1: Fit by width (if new_height would be <= canvas_height)
            new_width = canvas_width
            new_height = int(new_width / original_aspect_ratio)

            if new_height > canvas_height:
                # Option 2: Fit by height (if Option 1 made image too tall)
                new_height = canvas_height
                new_width = int(new_height * original_aspect_ratio)

            # Ensure minimum size to avoid errors with very small windows
            if new_width <= 0 or new_height <= 0:
                return # Do nothing if dimensions are invalid

            # Resize the image using Pillow (Image.resize)
            # Use Image.LANCZOS for high-quality downscaling/upscaling
            resized_image = self.original_image.resize((new_width, new_height), Image.LANCZOS)

            # Convert to PhotoImage for Tkinter
            self.tk_image = ImageTk.PhotoImage(resized_image)

            # Update the image on the canvas
            # self.canvas_item = self.canvas.create_image(0, 0, anchor=tk.NW, image=self.tk_image)
            # ^ This line creates new image objects; better to modify existing one

            # Update the existing image object and center it
            x_center = (canvas_width - new_width) // 2
            y_center = (canvas_height - new_height) // 2
            self.canvas.coords(self.canvas_item, x_center, y_center)
            self.canvas.itemconfig(self.canvas_item, image=self.tk_image)


# --- Main execution ---
if __name__ == "__main__":
    # IMPORTANT: Adjust this path to your image
    image_file_path = r"C:\temp\cb\img.jpg"

    root = tk.Tk()
    app = ImageApp(root, image_file_path)
    root.mainloop()

Enter fullscreen mode Exit fullscreen mode

Comments 0 total

    Add comment