Manejo de imágenes y rutas con Tkinter -100 días de Python #14
Este día número 14 lo vamos a aprovechar para el manejo de imágenes y rutas mediante el uso de Python y sus módulos Tkinter y Pillow.
Cambiar el icono de la ventana de Tkinter
Empecemos por algo fácil. Vamos a cambiar el icono que viene por defecto en la ventana que genera Tkinter.
En el proyecto de Python, vamos a crear en la raíz una nueva carpeta, la cual, utilizaremos para las imágenes.
Para cambiar el icono de la ventana, lo podemos hacer con iconbitmap().
Importar directorios
Antes de cargar la imagen, vamos a realizar la importación de un nuevo módulo llamado «os», para el manejo de tareas en el sistema operativo.
De este módulo, vamos a utilizar lo siguiente:
#Importaciones from tkinter import * import os # Directorio principal carpeta_principal = os.path.dirname(__file__) # Directorio de imágenes carpeta_imagenes = os.path.join(carpeta_principal, "imagenes") #Creación de la ventana principal root = Tk() #Título de la ventana root.title("Curso de Tkinter de Programación Fácil") #Bucle de ejecución root.mainloop()
Por un lado (línea 6), cargamos la carpeta principal, la raíz del directorio. La variable especial «__file__
» nos sirve para sustituir por cualquier nombre de directorio en este caso.
Ahora que ya tenemos la raíz cargada en el programa, podemos usarla para almacenar rutas de otras carpetas como en la línea 8.
Una vez hecho esto, podremos trabajar cómodamente con imágenes u otros archivos en el programa.
El icono, lo he creado como .ico. En formato .png no se visualiza. Las dimensiones son de 128×128, pero puede ser un valor inferior, el icono se muestra muy pequeño.
Aquí tienes los archivos que he utilizado (en el vídeo) para realizar todo el día de hoy, por si lo quieres hacer como yo.
#Importaciones from tkinter import * import os # Directorio de imágenes principal carpeta_principal = os.path.dirname(__file__) # Directorio de imágenes carpeta_imagenes = os.path.join(carpeta_principal, "imagenes") #Creación de la ventana principal root = Tk() #Título de la ventana root.title("Curso de Tkinter de Programación Fácil") #Icono de la ventana root.iconbitmap(os.path.join(carpeta_imagenes, "icono.ico")) #Bucle de ejecución root.mainloop()
Módulo para imágenes
Podemos instalar un módulo que no está integrado en Python llamado «Pillow», el cual permite procesar mejor las imágenes y tiene muchos métodos para trabajar con ellas.
Te dejo en este enlace la referencia a este gran módulo.
Instalar Pillow en Python
Para instalar Pillow vamos a poner en la Terminal lo siguiente:
pip install Pillow
Si te aparece «Successfully installed Pillow», quiere decir que se te ha instalado correctamente. El warning es porque hay una versión más moderna de PIP.
Actualizar PIP
Para actualizar PIP, pon este comando en la terminal:
pip install --upgrade pip
Ahora, debes realizar la importación de Pillow. Lo haremos así:
from PIL import *
Debes saber algo de la importación. Si la haces así, tu programa va a importar todo lo que contiene el módulo Pillow. Lo mismo con cualquier otro módulo. Ahora que estás aprendiendo, está bien, pero cuando empieces a crear programas propios y aprendas como funcionan los módulos que utilizamos, deberías importar solo las partes necesarias. Mira un ejemplo:
from PIL import ImageTk, ImageColor, ImageDraw
Con esto, solo podrás utilizar estas tres partes (módulos dentro del módulo) del conjunto del módulo, el cual tiene muchas.
Mostrar una imagen en Tkinter
Empecemos mostrando una imagen cualquiera.
La vamos a colocar en otra carpeta dentro de «imagenes». Así queda mi proyecto:
Las imágenes que pongamos en el programa, se deberán mostrar sobre algún elemento de Tkinter. En el código, una etiqueta (Label()).
De momento, solo necesitamos «ImageTk» e «Image» del módulo «Pillow» (línea 4).
En la línea 10, he creado la ruta hacia la nueva carpeta «paisajes».
En la 20, guardo la imagen en una variable. Necesitamos PhotoImage() que pertenece a ImageTk e Image.open() para indicar la ruta del archivo de imagen.
En la 21 creo una etiqueta que lleva la imagen. Así la muestro de alguna forma en el programa.
#Importaciones from tkinter import * import os from PIL import ImageTk,Image # Directorio de imágenes principal carpeta_principal = os.path.dirname(__file__) # Directorio de imágenes carpeta_imagenes = os.path.join(carpeta_principal, "imagenes") carpeta_paisajes = os.path.join(carpeta_imagenes, "paisajes") #Creación de la ventana principal root = Tk() #Título de la ventana root.title("Curso de Tkinter de Programación Fácil") #Icono de la ventana root.iconbitmap(os.path.join(carpeta_imagenes, "icono.ico")) #Carga de imagen nieve = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_paisajes, "nieve.jpg"))) etiqueta = Label(image=nieve) etiqueta.pack() #Bucle de ejecución root.mainloop()
La imagen en mi caso sale muy grande. Depende de la resolución que tenga. Si estás en Windows, puedes utilizar PowerToys para redimensionarla o algún otro programa como Photoshop o Gimp.
Redimensionar imagen
Sin cambiar el tamaño desde ningún programa, podemos redimensionar las imágenes desde el código, aunque piensa, que si no vas a necesitar la resolución grande nunca en tu programa, estarás desperdiciando recursos. Solo tienes que añadir el resize() a la imagen. El primer argumento (350) es el tamaño «width» (ancho) en píxeles y el otro el «height» (alto).
nieve = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_paisajes, "nieve.jpg")).resize((350,200)))
Redondear bordes de la imagen
Desde Python, podemos añadir un redondeo a las esquinas de las imágenes, sin embargo, es algo complicado. Podemos utilizar métodos más eficaces como editar la imagen con algún programa de edición gráfica. Yo voy a usar una aplicación web muy sencilla pero efectiva llamada Pinetools.
Hasta Windows 10, puede que no quisiéramos redondear las imágenes que ocupaban toda la ventana del programa, sin embargo, si estás en W11, verás que la imagen es rectangular y la ventana tiene bordes redondeados. Así que vamos a redondear un poco las esquinas para que quede mejor.
Guarda la imagen junto a la otra. Piensa que para que queden los bordes transparentes tiene que ser una imagen .png. Le ponemos el nuevo nombre, en mi caso «nieve-redondeada.png» y listo.
nieve = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_paisajes, "nieve-redondeada.png")).resize((400,225)))
hola buenas, estoy teniendo un problema un tanto peculiar, al momento de dar la ruta >>root.iconbitmap(os.path.join(carpeta_imagenes, «icono.ico»))<< me dice que la imagen o archivo .ico no existe. Pero si la busco ahi esta, ya intente mover .py a la misma carpeta o meter la imagen en otra carpeta. y sin resultado hasta le hice manejo de excepciones pero los print me dicen que no existe
Me sucede lo mismo. No supe como resolverlo.
me aparece este error de código:
File «/usr/lib/python3.11/tkinter/__init__.py», line 2136, in wm_iconbitmap
return self.tk.call(‘wm’, ‘iconbitmap’, self._w, bitmap)
Tengo un problema con Pillow, ha descargado con éxito, y el pip está actualizado, pero a la hora de querer importarlo me indica: » La importación ‘PIL’ no se ha podido resolver desde el origen»
Buenas… Tengo un problema con Pillow, ha descargado con éxito, y el pip está actualizado, pero a la hora de querer importarlo me indica: » La importación ‘PIL’ no se ha podido resolver desde el origen» y no me deja continuar, por lo que tampoco puedo seguir con el curso 🙁
Gracias por lo que haces y por el tiempo que le dedicas a ello. Así se aprende de una manera formidable algo que no todo el mundo puede costearse.
De nuevo gracias por todo y un saludo.