Visualizador de imágenes con Python y Tkinter

PythonPythonBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este proyecto, crearemos una aplicación de visualizador de imágenes utilizando Python y Tkinter. El visualizador de imágenes te permitirá abrir un archivo de imagen, mostrarlo y realizar acciones como ampliar, achicar y rotar la imagen. Utilizaremos la biblioteca PIL (Python Imaging Library) para manejar las operaciones de imagen y Tkinter para crear la interfaz gráfica de usuario.

👀 Vista previa

Vista previa de la aplicación de visualizador de imágenes

🎯 Tareas

En este proyecto, aprenderás:

  • Cómo crear una aplicación GUI utilizando Tkinter.
  • Cómo manejar la carga y visualización de imágenes utilizando PIL.
  • Cómo implementar la funcionalidad de ampliar, achicar y rotar la imagen mostrada.

🏆 Logros

Después de completar este proyecto, podrás:

  • Desarrollar una aplicación funcional de visualizador de imágenes utilizando Python y Tkinter.
  • Integrar capacidades de procesamiento de imágenes utilizando la biblioteca PIL.
  • Implementar características básicas de manipulación de imágenes como el zoom y la rotación.

Crear los archivos del proyecto

Primero, crea un nuevo archivo llamado ~/project/image_viewer.py y dile que lo abra en un editor de texto o un entorno de desarrollo integrado (IDE).

cd ~/project
touch image_viewer.py
✨ Revisar Solución y Practicar

Importar las bibliotecas necesarias

En el archivo image_viewer.py, importa las bibliotecas necesarias:

import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from PIL import Image, ImageTk
import os

La biblioteca tkinter proporciona la funcionalidad para crear elementos de interfaz gráfica de usuario, filedialog nos permite abrir un cuadro de diálogo de archivos para seleccionar un archivo de imagen, messagebox se utiliza para mostrar mensajes al usuario, PIL se utiliza para el procesamiento de imágenes y os proporciona funciones para interactuar con el sistema operativo.

✨ Revisar Solución y Practicar

Crear la clase ImageViewer

Define una nueva clase llamada ImageViewer que manejará la aplicación de visualizador de imágenes:

class ImageViewer:
    def __init__(self, root):
        self.root = root
        self.root.title('LabEx Image Viewer')
        self.root.geometry('800x600')
        self.root.configure(background='white')

        self.image_label = tk.Label(self.root)
        self.image_label.pack()

        self.control_frame = tk.Frame(self.root)
        self.control_frame.pack()

        self.open_button = tk.Button(self.control_frame, text='Open', command=self.open_image)
        self.open_button.pack(side='left')

        self.close_button = tk.Button(self.control_frame, text='Quit', command=self.root.quit)
        self.close_button.pack(side='left')

        self.zoom_in_button = tk.Button(self.control_frame, text='Zoom In', command=self.zoom_in)
        self.zoom_in_button.pack(side='left')

        self.zoom_out_button = tk.Button(self.control_frame, text='Zoom Out', command=self.zoom_out)
        self.zoom_out_button.pack(side='left')

        self.rotate_button = tk.Button(self.control_frame, text='Rotate', command=self.rotate)
        self.rotate_button.pack(side='left')

        self.current_image_path = ''
        self.zoom_level = 1

En el método __init__, inicializamos la ventana principal con un título, un tamaño y un color de fondo. Luego, creamos una etiqueta para mostrar la imagen y un marco para contener los botones de control (Abrir, Salir, Zoom In, Zoom Out, Rotar). También definimos variables de instancia para llevar un registro de la ruta de la imagen actual y el nivel de zoom.

✨ Revisar Solución y Practicar

Implementar el método open_image

Agrega el método open_image a la clase ImageViewer:

    def open_image(self):
        self.current_image_path = filedialog.askopenfilename(defaultextension=".jpg",
            filetypes=[("All Files", "*.*"), ("JPEG", ".jpg"), ("PNG", ".png"), ("GIF", ".gif")])
        if self.current_image_path:
            self.load_image()

El método open_image abre un cuadro de diálogo de archivos para seleccionar un archivo de imagen. Establece la variable current_image_path en la ruta del archivo seleccionado y llama al método load_image para mostrar la imagen.

✨ Revisar Solución y Practicar

Implementar el método load_image

Implementa el método load_image:

    def load_image(self):
        image = Image.open(self.current_image_path)

        ## Redimensionar la imagen para su visualización
        max_size = (600, 600)
        image.thumbnail(max_size)

        ## Guardar una referencia a la imagen original (para zoom/rotación)
        self.original_image = image

        ## Crear una imagen compatible con Tkinter
        self.tk_image = ImageTk.PhotoImage(image)
        self.image_label.configure(image=self.tk_image)

        self.zoom_level = 1

El método load_image abre el archivo de imagen seleccionado utilizando el método Image.open de PIL. Redimensiona la imagen para que quepa dentro de un tamaño máximo de 600x600 píxeles utilizando el método thumbnail. Luego, guarda una referencia a la imagen original con fines de zoom y rotación. A continuación, crea una imagen compatible con Tkinter utilizando ImageTk.PhotoImage y actualiza la etiqueta de imagen para mostrar la imagen cargada. Finalmente, establece el nivel de zoom inicial en 1.

✨ Revisar Solución y Practicar

Implementar el método zoom_in

Implementa el método zoom_in:

    def zoom_in(self):
        if not self.current_image_path:  ## No image loaded
            return
        self.zoom_level *= 1.1  ## Increase zoom level by 10%
        self.zoom_or_rotate_image()

El método zoom_in verifica si se ha cargado una imagen. Si no se ha cargado ninguna imagen, devuelve. De lo contrario, aumenta el nivel de zoom en un 10% y llama al método zoom_or_rotate_image para actualizar la imagen mostrada.

✨ Revisar Solución y Practicar

Implementar el método zoom_out

Implementa el método zoom_out:

    def zoom_out(self):
        if not self.current_image_path:  ## No image loaded
            return
        if self.zoom_level < 0.1:  ## Limit outwards zoom
            return
        self.zoom_level *= 0.9  ## Decrease zoom level by 10%
        self.zoom_or_rotate_image()

El método zoom_out verifica si se ha cargado una imagen. Si no se ha cargado ninguna imagen, devuelve. Si el nivel de zoom ya es inferior a 0.1, lo que significa que la imagen está deszoomificada al límite, devuelve. De lo contrario, disminuye el nivel de zoom en un 10% y llama al método zoom_or_rotate_image para actualizar la imagen mostrada.

✨ Revisar Solución y Practicar

Implementar el método rotate

Implementa el método rotate:

    def rotate(self):
        if not self.current_image_path:  ## No image loaded
            return
        self.original_image = self.original_image.rotate(-90)
        self.zoom_or_rotate_image()

El método rotate verifica si se ha cargado una imagen. Si no se ha cargado ninguna imagen, devuelve. De lo contrario, rota la imagen original en -90 grados utilizando el método rotate de PIL y llama al método zoom_or_rotate_image para actualizar la imagen mostrada.

✨ Revisar Solución y Practicar

Implementar el método zoom_or_rotate_image

Implementa el método zoom_or_rotate_image:

    def zoom_or_rotate_image(self):
        ## Zoom and rotate original image, convert to Tk image, and display
        new_image = self.original_image.resize((int(self.original_image.width * self.zoom_level),
                                                int(self.original_image.height * self.zoom_level)))
        self.tk_image = ImageTk.PhotoImage(new_image)
        self.image_label.configure(image=self.tk_image)

El método zoom_or_rotate_image redimensiona la imagen original según el nivel de zoom actual. Crea una nueva imagen con el tamaño actualizado utilizando el método resize de PIL. Luego, convierte la nueva imagen en una imagen compatible con Tkinter utilizando ImageTk.PhotoImage y actualiza la etiqueta de imagen para mostrar la imagen actualizada.

✨ Revisar Solución y Practicar

Crear el bucle principal de la aplicación

Agrega el siguiente código al final del archivo image_viewer.py para crear el bucle principal de la aplicación:

if __name__ == '__main__':
    root = tk.Tk()
    app = ImageViewer(root)
    root.mainloop()

Este código crea una ventana principal de Tkinter, inicializa una instancia de la clase ImageViewer y comienza el bucle principal de la aplicación.

Vaya a la Escritorio y ejecute el archivo image_viewer.py para probar la aplicación. Debería ver la siguiente ventana:

python image_viewer.py
Tkinter application window
✨ Revisar Solución y Practicar

Resumen

¡Felicidades! Has creado una aplicación de visualizador de imágenes utilizando Python y Tkinter. La aplicación te permite abrir un archivo de imagen, mostrarla y realizar acciones como ampliar, achicar y rotar la imagen. Has aprendido a usar la biblioteca PIL para el procesamiento de imágenes y Tkinter para crear la interfaz gráfica de usuario. Siéntase libre de personalizar aún más la aplicación o explorar características adicionales.