· Cambiar idioma (Actualmente: Español)

Python, GTK: Redimensionar imágenes (GTK Image, GDK Pixbuf)

Agosto 28, 2021 13:29 -0500

En estos días, escribiendo una aplicación gráfica en Python y GTK, me surgió la necesidad de mostrar imágenes en tamaños específicos diferentes a sus tamaños originales. Lo pude hacer, pero me pareció difícil encontrar cómo. Navegar la documentación de GTK no fue suficiente. Además, los ejemplos relacionados que encontré en la Web no eran del todo lo que buscaba o usaban API desactualizadas. Por eso dejo acá unos ejemplos, que tal vez le sirvan a alguien más.

Primero, descargue los archivos de ejemplo. Si usa GNU Guix, puede iniciar un entorno de desarrollo desechable para ejecutar los ejemplos, así:

cd carpeta-de-ejemplos
guix environment -m manifest.scm

Una vez listo el entorno, puede ejecutar los ejemplos normalmente con Python. Por ejemplo:

python3 example-01.py

Si no usa GNU Guix, instale los paquetes listados en el archivo manifest.scm con los medios de su sistema.

Al ejecutar los ejemplos, debería ver las ventanas que se muestran en la Figura 1.

Figura 1
Figura 1. Ventanas que se abren al ejecutar el Ejemplo 1 (example-01.py), Ejemplo 2 (example-02.py) y Ejemplo 3 (example-03.py), respectivamente.

El Ejemplo 1 es simplemente una ventana que muestra la imagen en su tamaño original (200×200 píxeles) por medio de un objeto Gtk.Image creado con el método constructor new_from_file (ver Código 1).

import gi
gi.require_version("Gtk", "3.0")

from gi.repository import Gtk


def on_activate(app):
    window = Gtk.ApplicationWindow(application=app)
    image = Gtk.Image.new_from_file("icon.svg")

    window.set_default_size(300, 300)
    window.add(image)
    window.show_all()


# Create a new application
app = Gtk.Application(application_id="com.example.GtkApplication")
app.connect("activate", on_activate)

# Run the application
app.run(None)
      
Código 1. Programa del Ejemplo 1 (example-01.py).

El Ejemplo 2 muestra la misma imagen, pero ahora reducida a 50×50 píxeles. Y aquí está lo importante y lo que fue difícil de encontrar en la documentación de GTK: el cambio de tamaño se logra es creando un objeto del tipo GdkPixbuf.Pixbuf (un búfer de píxeles) por medio del método constructor new_from_file_at_size y luego construyendo una Gtk.Image a partir del objeto Pixbuf. (ver Código 2).

import gi
gi.require_version("GdkPixbuf", "2.0")
gi.require_version("Gtk", "3.0")

from gi.repository import GdkPixbuf, Gtk


def on_activate(app):
    window = Gtk.ApplicationWindow(application=app)
    pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
        "icon.svg",
        50,  # px width
        50   # px height
    )
    image = Gtk.Image.new_from_pixbuf(pixbuf)

    window.set_default_size(300, 300)
    window.add(image)
    window.show_all()


# Create a new application
app = Gtk.Application(application_id='com.example.GtkApplication')
app.connect('activate', on_activate)

# Run the application
app.run(None)
      
Código 2. Programa del Ejemplo 2 (example-02.py).

El Ejemplo 3 es prácticamente igual en resultado que el Ejemplo 2. La única diferencia es que usa el método scale_simple de un objeto Pixbuf para escalar la imagen especificando un parámetro adicional: el tipo de interpolación que se debe usar para transformar la imagen (ver Código 3). Pero para mi necesidad, el método del Ejemplo 2 fue suficiente.

import gi
gi.require_version("GdkPixbuf", "2.0")
gi.require_version("Gtk", "3.0")

from gi.repository import GdkPixbuf, Gtk


def on_activate(app):
    window = Gtk.ApplicationWindow(application=app)
    pixbuf = GdkPixbuf.Pixbuf.new_from_file("icon.svg")
    resized_pixbuf = pixbuf.scale_simple(
        50,  # px width
        50,  # px height
        GdkPixbuf.InterpType.BILINEAR)
    image = Gtk.Image.new_from_pixbuf(resized_pixbuf)

    window.set_default_size(300, 300)
    window.add(image)
    window.show_all()


# Create a new application
app = Gtk.Application(application_id='com.example.GtkApplication')
app.connect('activate', on_activate)

# Run the application
app.run(None)
      
Código 3. Programa del Ejemplo 3 (example-03.py).

Hay que parchar la documentación de GTK para que enlace los tipos de datos que no hacen parte de GTK a sus respectivas definiciones. Pixbuf es uno de varios. Así sería más fácil encontrar las cosas. Pero la documentación y el sitio web de GTK están mejorando mucho en general.

Temas relacionados: