4.2. Nivel Intermedio

4.2.1. Cuadrados (squares.py)

4.2.1.1. Descripción

Este programa es un poco inútil, pero nos va a servir para poder entender algunas formas de trabajo repetitivas. Lo único que hace es crear un número de cruadrados de tamaño aleatorio alrededor de nuestra imagen. El número de cuadrados y los colores de estos se lo pasaremos por medio de nuestro script.

4.2.1.2. Como usarlo

Para usarlo sólo tenemos que crear una imagen nueva del tamaño que queramos y ejecutar nuestro script. Luego sólo tendremos que colocar los parámetros que queramos.

4.2.1.3. Código

De la línea 78 a la 83 vemos los parámetros de nuestro script. Los primero que vemos es el número de cuadrados que queremos dibujar, luego el tamaño de la ventana que vamos a crear y por últimos 3 colores. Estos colores se irán alternando y cada cuadrado se ira dibujando de un color de estos.

Ahora empezamos a trabajar. En la línea 18 cambiamos el tamaño de la imagen con los parámetros que le hemos pasado por medio del script. En la línea 21 y 22 ponemos el fondo de color blanco.

Lo siguiente que vamos hacer es crear el número de cuadrados que nos ha dicho el usuario. Hay varias formas de hacerlo pero nosotros lo haremos mediante un bucle "while". Para ello necesitamos un contador, variable "cont" en nuestro programa, y en cada vuelta dentro del bucle "while" le sumaremos 1. La condición será que mientras "cont" sea menor a el número de cuadrados que ha puesto el usuario en el script que siga dentro del bucle "while". Por supuesto dentro de este bucle iremos creando los cuadrados. Veamos como lo hacemos.

En la línea 25 creamos la variable contador y la ponemos a 0. En la línea 26 empezamos el bucle con la condición que hemos explicado antes y al final del bucle, línea 58, sumamos 1 a nuestro contador. De las líneas 27 a la 56 crearemos nuestro cuadrado, este código se repetirá el número de veces que nosotros queremos, o sea, el número que ha puesto el usuario que quiere que se repita.

Para crear los cuadrados lo primero que hacemos es establecer la posición del cuadrado y el tamaño de este. Para ello usamos las variables w (ancho), h (alto), x (posición x en la imagen) e y (posición y en la imagen). De la línea 34 a la 37 puede verlo. Hay una nueva función que es "random.randint". Lo primero que tenemos que saber que para poder trabajar con esta función tenemos que importar el módulo "ramdom" (lo podéis ver en la línea 9). A esta función se le pasan dos números y Python te dará un número aleatorio entre esos dos. En la línea 40 vemos como creamos una selección cuadrada con las variables que acabamos de establecer. En la línea 40 creamos un borde de esa selección de tamaño 2. El tamaño también podríamos pasarlo por medio del script y que fuese el usuario quien decidiese, pero para este ejercicio mejor dejarlo como está. De la línea 46 a la 52 vamos a elegir el color que queremos usar para el cuadrado. En la 46 creamos una variable llamada "color" que obtendrá un número aleatoriamente del 1 al 3. En la siguientes líneas vemos como según el número sea uno u otro utilizamos uno de los colores que hemos pasado por medio del script estableciéndolo como fondo y en la línea 54 rellenamos de ese color la selección que hemos creado, formando el cuadrado. Por último en la línea 56 eliminamos la selección.

01 >>> #!/usr/bin/env python

02 >>> # Script para Gimp en Python
03 >>> # Realizado por Fco. Javier Pérez Pacheco como ejercicio
04 >>> # para el artículo "Python-fu para no programadores".
05 >>> # Este ejercicio genera un número de cuadrados aleatoriamente
06 >>> # de diferentes colores en una imagen

07 >>> # importamos los módulos necesarios
08 >>> from gimpfu import *
09 >>> import random

10 >>> # definimos las funciones necesarias
11 >>> def Squares(img, drawable, nSquares, width, height, color1, color2, color3):
12 >>>     # comenzamos a agrupar el UNDO
13 >>>     pdb.gimp_image_undo_group_start(img)

14 >>>     # guardamos el color actual de fondo de la paleta para al final
15 >>>     # volver a colocarlo

16 >>>     old_background = gimp.get_background()

17 >>>     # ponemos el ancho y alto de la imagen

18 >>>     pdb.gimp_image_scale(img, width, height)

19 >>>     # ponemos el blanco como color de fondo de la paleta y 
20 >>>     # rellenamos la capa del color de fondo de la paleta

21 >>>     pdb.gimp_context_set_background((255,255,255))
22 >>>     pdb.gimp_edit_fill(img.active_layer, BACKGROUND_FILL)

23 >>>     # creamos los cuadrados, para eso utilizamos un bucle while
24 >>>     # que empiece desde 0 hasta que no tengamos mas cuadrados

25 >>>     cont = 0

26 >>>     while(cont<nSquares):
27 >>>         # con random establecemos el tamaño (w y h) que será
28 >>>         # un numero aletario entre 50 y 150 y luego
29 >>>         # establecemos la posicion x e y del cuadrado
30 >>>         # que podra ser por cualquier parte de la imagen
31 >>>         # fijate como los valores maximo y minimo del random
32 >>>         # de la posicion x,y sirven para que el cuadrado
33 >>>         # no salga fuera de la imagen
34 >>>         w = random.randint(50, 150)
35 >>>         h = random.randint(50, 150)
36 >>>         x = random.randint(0, width-w)
37 >>>         y = random.randint(0, height-h)

38 >>>         # con los valores anterior crear una seleccion que 
39 >>>         # empieza en (x,y) y tiene un tamaño (w,h)
40 >>>         pdb.gimp_rect_select(img, x, y, w, h, 0, 0, 0)

41 >>>         # sobre esta seleccion hacemos un borde de tamaño 2
42 >>>         pdb.gimp_selection_border(img, 2)

43 >>>         # ahora seleccionamos uno de los 3 colores aleatoriamente
44 >>>         # recuerda que tenemos que establecerlo como fondo
45 >>>         # de la paleta de colores

46 >>>         color = random.randint(1, 3)
47 >>>         if color == 1:
48 >>>             pdb.gimp_context_set_background(color1)
49 >>>         elif color == 2:
50 >>>             pdb.gimp_context_set_background(color2)
51 >>>         else:
52 >>>             pdb.gimp_context_set_background(color3)

53 >>>         # rellenamos la seleccion (cuadrado) con el color de fondo
54 >>>         pdb.gimp_edit_fill(img.active_layer, BACKGROUND_FILL)

55 >>>         # le decimos a gimp que elimine la seleccion
56 >>>         pdb.gimp_selection_none(img)

57 >>>         # sumamos uno a nuestro contador
58 >>>         cont = cont + 1

59 >>>     # ya tenemos todos los cuadrados dibujados
60 >>>     # ahora como lo prometido es deuda, establecemos el color
61 >>>     # de fondo con el color que guardamos al principio

62 >>>     pdb.gimp_context_set_background(old_background)
	
63 >>>     # agrupamos UNDO
64 >>>     pdb.gimp_image_undo_group_end(img)

65 >>> # función principal
66 >>> if __name__ == '__main__':

67 >>>     # llamada a función register
68 >>>     register(
69 >>>         "cuadrados",
70 >>>         "Cuadrados",
71 >>>         "Cuadrados",
72 >>>         "Javi Pacheco",
73 >>>         "Javi Pacheco",
74 >>>         "2005",
75 >>>         "<Image>/Python-Fu/Ejemplos/2- Intermedio/Cuadrados",
76 >>>         "RGB*, GRAY*",
77 >>>         [
78 >>>         (PF_SPINNER, "nSquares", "Numero de cuadrados", 20, (0, 1000, 1)),
79 >>>         (PF_SPINNER, "width", "Ancho Imagen", 500, (0, 1000, 1)),
80 >>>         (PF_SPINNER, "height", "Alto Imagen", 500, (0, 1000, 1)),
81 >>>         (PF_COLOR, "color1", "Color 1", (255,0,0)),
82 >>>         (PF_COLOR, "color2", "Color 2", (0,255,0)),
83 >>>         (PF_COLOR, "color3", "Color 3", (0,0,255))
84 >>>         ],
85 >>>         [],
86 >>>         Squares)
87 >>>     main()
				

4.2.2. Crear Mosaico (mosaic.py)

4.2.2.1. Descripción

Quizás este script puede ser interesante para alguien. La idea es crear un mosaico de imágenes con las fotos de un directorio. En nuestro script tenemos que decirle el directorio donde tenemos las imágenes, el número de imágenes por fila y el tamaño final de cada una de ellas.

Imagínate que vienes de tus vacaciones y has hecho 50 fotos. Puedes crear una mosaico de imágenes con este script para que la vean tus amigos y que te digan cuales son las fotos que quieren que les envies por correo.

Atención

El problema de este script es que sólo funciona en versiones superiores a la 2.2. Así que sólo funciona actualmente en versiones de desarrollo. La función "gimp_file_load_layer" no existe en la versión 2.2.x de Gimp y por mucho que lo he intentado no he podido lograr insertar una imagen directamente en una capa, estoy seguro que se puede, pero yo no lo he conseguido. Si alguien lo sabe o lo consigue, por favor, que me lo comente.

Ejemplo de imagen creada con este script.

4.2.2.2. Como usarlo

Lo primero que tenemos que hacer es crearnos un directorio con todas las imágenes que queramos que formen nuestro mosaico. Es importante que sólo contenga imágenes, no puede tener otro tipo de archivo ya que no funcionará. Luego nos vamos a Gimp, abrimos creamos una imagen nueva y ejecutamos el script.

4.2.2.3. Código

Lo primero es fijarnos en los parámetros que le tenemos que pasar al script. Entre las líneas 67 a la 70 los podemos encontrar. Los parámetros son: el directorio donde se encuentran las imágenes, el número de imágenes por columna y el tamaño de cada una de las imágenes.

Lo primero que tenemos que hacer es recorrer el directorio para saber cuantas imágenes tenemos. No es lo mismo que tengamos 50 imágenes a que tengamos 4, ya que este número nos dará el tamaño de la imagen final. En la línea 15 creamos una nueva variable "nPhotos" que contendrá el número de fotos del directorio de imágenes. Luego recorremos el directorio, para ello usamos:

files = os.listdir(path)

Que nos creará un array llamado "files" con todos los archivos de nuestro directorio. Para poder hacerlo hacemos uso del módulo "os" que para poder usarlo tenemos que importarlo en el script (línea 8). Ahora recorremos los archivos con:

for file in files:

Y por cada uno de los archivos iremos sumando 1 a la variable nPhotos, por lo que al final tendremos el número de fotos del directorio.

Ahora necesitamos saber el número de filas que tendrá la imagen. Para ello, como tenemos el número de columnas, dividimos el número de fotos por el de columnas y tendremos el número de filas como podemos ver en la línea 20. En la línea 21 y 22 en el caso que sea una división entera le sumamos uno al número de filas para tener el número de filas correctamente. En la línea 25 y 26 calculamos el tamaño de la imagen final multiplicando debidamente y en la línea 27 escalamos la imagen. En la línea 29 rellenamos del color de fondo de la paleta.

Ahora llegamos a la parte importante. Vamos a ir cargando las imágenes del directorio en un layer al tamaño que nos ha dicho el usuario. Para ello cargamos la imagen y la desplazamos debidamente a su sitio. Creamos 4 nuevas variables de la línea 30 a la 33 que nos ayudarán hacer el trabajo. Luego recorremos de nuevo todas las imágenes pero esta vez las cargaremos en nuestra imagen final. El trabajo de cargar y colocar la imagen se encuentra de la línea 38 a la 51.

Primero cargamos la imagen en una capa:

photo_layer = pdb.gimp_file_load_layer(img, path+os.sep+file)

A la función "gimp_file_load_layer", se le pasan dos parámentros, el primero la imagen y luego la ruta de la imagen que queremos cargar en la capa. Fijémonos como creamos la ruta.

path + os.sep + file

La variable "path" es el directorio donde se encuentra la imagen y esta variable ha sido enviada por el usuario por medio del script. La variable "os.sep" nos da la barra separadora de rutas del sistema operativo en el que estamos trabajando. En el caso de Linux la barra separadora es "/" mientras que en Windows es "\", si usamos esta variable del módulo "os" (cargado en la línea 8) no tendremos problemas de portabilidad. Por último tenemos la variable "file" que contiene el nombre del archivo en el que nos encontramos. La suma de todo es la ruta absoluta de la imagen que queremos cargar.

Después de cargar añadimos la capa (línea 41), la escalamos (linea 43) y en la línea 45 movemos la capa al lugar que queremos. En las líneas siguiente preparamos las variables "move_x" y "move_y" para la siguiente imagen que vamos a cargar.

01 >>> #!/usr/bin/env python

02 >>> # Script para Gimp en Python
03 >>> # Realizado por Fco. Javier Pérez Pacheco como ejercicio
04 >>> # para el artículo "Python-fu para no programadores".
05 >>> # Crea un mosaico de las imágenes que se encuentran en una carpeta

06 >>> # importamos los módulos necesarios
07 >>> from gimpfu import *
08 >>> import os

09 >>> # definimos las funciones necesarias
10 >>> def Mosaic(img, drawable, path, columns, width_photo, height_photo):
11 >>>     # comenzamos a agrupar el UNDO
12 >>>     pdb.gimp_image_undo_group_start(img)

13 >>>     # comprobamos el número de fotos jpg que hay en el directorio
14 >>>     # recorriendolo completamente

15 >>>     nPhotos = 0

16 >>>     files = os.listdir(path)
17 >>>     for file in files:
18 >>>         nPhotos = nPhotos+ 1 

19 >>>     # comprobamos el número de filas

20 >>>     rows = nPhotos/columns

21 >>>     if nPhotos%columns!=0:
22 >>>         rows = rows + 1

23 >>>     # ya que sabemos el numero de filas y columnas y el tamños de los item
24 >>>     # calculamos el ancho y alto de la imagen y lo establecemos

25 >>>     width_img = width_photo * columns
26 >>>     height_img = height_photo * rows 

27 >>>     pdb.gimp_image_scale(img, width_img, height_img)

28 >>>     # rellenamos la imagen del color de fondo de nuestra paleta

29 >>>     pdb.gimp_edit_fill(img.active_layer, BACKGROUND_FILL)

30 >>>     move_x = 0
31 >>>     move_y = 0
32 >>>     cont = 0
33 >>>     nRow = 0

34 >>>     # recorremos de nuevo todos los archivos y empezamos ya a cargarlos 
35 >>>     # en nuestra nueva imagen

36 >>>     files = os.listdir(path)
37 >>>     for file in files:
38 >>>         # cargamos la foto y creamos una nueva capa
39 >>>         photo_layer = pdb.gimp_file_load_layer(img, path+os.sep+file)
40 >>>         # añadimos la capa a nuestra imagen
41 >>>         pdb.gimp_image_add_layer(img, photo_layer, -1)
42 >>>         # escalamos el tamaño de la capa
43 >>>         pdb.gimp_layer_scale(photo_layer, width_photo, height_photo,0 )
44 >>>         # la trasladamos a su lugar según del desplamiento en x e y
45 >>>         pdb.gimp_layer_translate(photo_layer, move_x, move_y)
46 >>>         cont = cont + 1
47 >>>         # calculamos el desplazamiento par la siguiente imagen
48 >>>         if (cont%columns==0):
49 >>>             nRow = nRow + 1
50 >>>         move_x = width_photo * (cont%columns)
51 >>>         move_y = height_photo * nRow
		
	
52 >>>     # agrupamos UNDO
53 >>>     pdb.gimp_image_undo_group_end(img)

54 >>> # función principal
55 >>> if __name__ == '__main__':

56 >>>     # llamada a función register
57 >>>     register(
58 >>>         "mosaico",
59 >>>         "Mosaico",
60 >>>         "Mosaico",
61 >>>         "Javi Pacheco",
62 >>>         "Javi Pacheco",
63 >>>         "2005",
64 >>>         "<Image>/Python-Fu/Ejemplos/2- Intermedio/Mosaico (>Gimp2.2)",
65 >>>         "RGB*, GRAY*",
66 >>>         [
67 >>>             (PF_FILE, "path", "Directorio", ""),
68 >>>             (PF_SPINNER, "columns", "Numero fotos horizontal", 4, (0, 1000, 1)),
69 >>>             (PF_SPINNER, "width_photo", "Ancho foto", 200, (0, 1000, 1)),
70 >>>             (PF_SPINNER, "height_photo", "Alto foto", 200, (0, 1000, 1))
71 >>>         ],
72 >>>         [],
73 >>>         Mosaic)
74 >>>     main()
				

4.2.3. Crear texto (text.py)

4.2.3.1. Descripción

Con este script aprenderemos como colocar un texto dentro de nuestra imagen. Podremos seleccionar la fuente, tamaño, texto, etc.

Es importante saber que las fuentes que aparecen en nuestro script serán las fuentes que tengamos instaladas en el sistema operativo. Desde el menú de "Preferencias" de Gimp podemos agregar directorios de fuentes que no formen parte del sistema. Estas fuentes no aparecerán, para poder usarlas tienen que ser instaladas adecuadamente.

4.2.3.2. Como usarlo

Simplemente abre cualquier imagen y ejecuta el script.

4.2.3.3. Código

Primero vemos los parámetros del script que se encuentran de la línea 54 a la 58. Los parámetros son: el texto que queremos insertar, el color de la fuente, la fuente que queremos usar para el texto y la posición en la imagen.

Si nos fijamos, cuando selecionamos una fuente y su tamaño, se insertan en una caja de texto. Gimp no puede trabajar directamente con esa cadena, así que lo primero que tenemos que hacer es separar debidamente el nombre de la fuente del tamaño y es lo que hacemos en las líneas 21 y 22. Para hacerlo hacemos uso del módulo "re" que hemos importado con anterioridad en la línea 8. Aunque parece muy complicado, y realmente para personas que no tengas experiencia de programación lo es, siempre será igual, así que nada más que tenemos que copiar y pegar el código en nuestros scripts.

Una vez que hemos realizado lo más complicado hacemos la parte más sencilla. En la línea 24 creamos una capa con el texto. En la línea 27 y 28 bloqueamos la transparencia de la capa. Esto sólo hay que hacerlo en versiones superiores a la 2.3.x, y esa es la condición del "if" de la línea 27.

En la línea 31 y 32 coloreamos el texto del color que hemos pasado como parámetro en el script para finalizar estableciendo la capa en la imagen en la línea 34.

01 >>> #!/usr/bin/env python

02 >>> # Script para Gimp en Python
03 >>> # Realizado por Fco. Javier Pérez Pacheco como ejercicio
04 >>> # para el artículo "Python-fu para no programadores".
05 >>> # Este ejercicio crea un texto

06 >>> # importamos los módulos necesarios
07 >>> from gimpfu import *
08 >>> import re

09 >>> # definimos las funciones necesarias
10 >>> def Text(img, drawable, text, color, font, position_x, position_y):
11 >>>     # comenzamos a agrupar el UNDO
12 >>>     pdb.gimp_image_undo_group_start(img)

13 >>>     # guardamos el color actual de fondo de la paleta para al final
14 >>>     # volver a colocarlo

15 >>>     old_background = gimp.get_background()

16 >>>     # colocamos el texto
17 >>>     # para ello tenemos que recuperar la informacion de la caja de texto con la fuente
18 >>>     # la informacion es: tamaño, fuente del texto
19 >>>     # lo separamos usando el modulo "re" de python, pero tampoco tenemos que 
20 >>>     # preocuparnos porque siempre es igual

21 >>>     size_text = re.search(r' (\d+)$',font).group(1)
22 >>>     font_text = re.sub(size_text, '', font)

23 >>>     # creamos la capa con el texto en la posicion (x,y) que pongamos

24 >>>     layer_txt = pdb.gimp_text_fontname(img, drawable, position_x, position_y, text, -1, True,  size_text, POINTS, font_text)

25 >>>     # si la versión de gimp es 2.3.x o superior
26 >>>     # bloqueamos el alpha de la capa
27 >>>     if int(pdb.gimp_version().split(".")[0])==2 and int(pdb.gimp_version().split(".")[1])>2:
28 >>>         pdb.gimp_layer_set_lock_alpha(layer_txt, 255)

29 >>>     # para colorear bloquemos la capa y coloremos con el color de fondo
30 >>>     # que previamente hemos establecido con el color que seleccionemos

31 >>>     pdb.gimp_context_set_background(color)
32 >>>     pdb.gimp_edit_fill(layer_txt, BACKGROUND_FILL)

33 >>>     # ponemos la capa flotante como capa de la imagen
34 >>>     pdb.gimp_floating_sel_to_layer(layer_txt)

35 >>>     # ya tenemos todos los cuadrados dibujados
36 >>>     # ahora como lo prometido es deuda, establecemos el color
37 >>>     # de fondo con el color que guardamos al principio

38 >>>     pdb.gimp_context_set_background(old_background)
	
39 >>>     # agrupamos UNDO
40 >>>     pdb.gimp_image_undo_group_end(img)

41 >>> # función principal
42 >>> if __name__ == '__main__':

43 >>>     # llamada a función register
44 >>>     register(
45 >>>         "texto",
46 >>>         "Texto",
47 >>>         "Texto",
48 >>>         "Javi Pacheco",
49 >>>         "Javi Pacheco",
50 >>>         "2005",
51 >>>         "<Image>/Python-Fu/Ejemplos/2- Intermedio/Texto",
52 >>>         "RGB*, GRAY*",
53 >>>         [
54 >>>             (PF_STRING, "text", "Texto", "Colocar un texto"),
55 >>>             (PF_COLOR, "color", "Color", (0,0,0)),
56 >>>             (PF_FONT, "font","Fuente", "Sans 10"),
57 >>>             (PF_SPINNER, "position_x", "Posicion X", 50, (0, 9999999999, 1)),
58 >>>             (PF_SPINNER, "position_y", "Posicion Y", 50, (0, 9999999999, 1)),
59 >>>         ],
60 >>>         [],
61 >>>         Text)
62 >>>     main()