Programmation objet et géométrie/Objets en Python sous Gimp/Tracé de polygones en Python sous Gimp


Pour Python, un point est un tableau (de deux nombres, l'abscisse et l'ordonnée). Et un polygone est décrit par ses sommets, et sera donc représenté comme un tableau de points ... donc un tableau de tableaux!

C'est pour ce genre de représentations que la programmation objet facilite la compréhension, et raccourcit les scripts.

On va traiter un exemple, celui de la lemniscate de Bernoulli, représentée sous Gimp par une approximation polygonale.

LemniscateModifier

Représentation paramétriqueModifier

La lemniscate de Bernoulli est donnée par sa représentation paramétrique


 

Pour la représenter sous Gimp, on va choisir un certain nombre de valeurs de t, pour lesquelles on va calculer x et y. Mais quelques points représentent mal la lemniscate, alors on va les joindre par des segments, qui, s'ils sont assez nombreux, peuvent représenter sous Gimp des coups de pinceau.

Création du filtreModifier

Comme d'habitude, on importe les fonctions utiles pour que le script fonctionne (ici on a besoin des fonctions trigonométriques):

#!/usr/bin/env python


import math
from math import *
from gimpfu import *

ScriptModifier

Image et calqueModifier

La fonction qui implémente le filtre s'appellera python_lemniscate et aura pour variable une image (objet de type image). On récupère trois de ses propriétés:

  1. sa largeur
  2. sa hauteur
  3. son premier calque:
def python_lemniscate(img) :
	largeur=img.width
	hauteur=img.height
	calque=img.layers[0]

Les sommetsModifier

Les sommets du polygone, construits l'un après l'autres, seront stockés dans un tableau appelé sommets (quel nom original!). Pour utiliser ce tableau, Gimp aura besoin aussi du nombre de sommets, qui s'appellera ns.

InitialisationModifier

En phase de test, il est plus prudent de choisir une valeur faible pour ns: Ici on prend 6 sommets, ce qui aura pour effet de faire ressembler la lemniscate à une figure composée de deux carrés ayant un sommet commun. Donc ns est initialisé à 6. Et le tableau sommets est initialement vide:

	ns=6
	sommets=[]

BoucleModifier

C'est ici que tout va se passer: Dans la boucle, on va ns fois faire ceci:

  1. Calculer t (le paramètre)
  2. Calculer x avec la représentation paramétrique ci-dessus (mais en modifiant les unités du repère)
  3. Calculer y de même
  4. Créer le point de coordonnées x et y
  5. Stocker ce point dans le tableau sommets.

C'est presque plus court à écrire en Python qu'à décrire:

	for i in range(ns):
		t=2*pi/ns*i
		x=int(largeur/2+largeur/4*cos(t))
		y=int(hauteur/2+hauteur/4*sin(2*t))
		P=(x,y)
		sommets.extend(P)

FinModifier

Pour refermer le polygone, on remet ça une dernière fois: On crée le point initial à nouveau, et on le rajoute dans le tableau. Ainsi le tableau contiendra ns+1 points, donc 2ns+2 nombres entiers:

	x=int(largeur/2+largeur/4)
	y=int(hauteur/2)
	P=(x,y)
	sommets.extend(P)

Tracé au pinceauModifier

Pour demander à Gimp de tracer la lemniscate, on va choisir le pinceau par défaut (celui qui est sélectionné au lancement du filtre), lui fournir

  1. le calque sur lequel il va dessiner
  2. la longueur du tableau des sommets
  3. le tableau proprement dit

Le pinceau est appelé dans la base de donnée des procédures (pdb) de Gimp:

	pdb.gimp_paintbrush_default(calque,2*ns+2,sommets)

RécapitulatifModifier

L'objet lemniscate est donc celui-ci:

def python_lemniscate(img) :
	largeur=img.width
	hauteur=img.height
	calque=img.layers[0]
	ns=6
	sommets=[]
	for i in range(ns):
		t=2*pi/ns*i
		x=int(largeur/2+largeur/4*cos(t))
		y=int(hauteur/2+hauteur/4*sin(2*t))
		P=(x,y)
		sommets.extend(P)
	x=int(largeur/2+largeur/4)
	y=int(hauteur/2)
	P=(x,y)
	sommets.extend(P)
	pdb.gimp_paintbrush_default(calque,2*ns+2,sommets)

Enregistrement du filtreModifier

Pour que le filtre soit accessible depuis le Gimp, on doit ajouter quelque chose comme ceci en bas du script:

register(
       	"lemniscate",
	"Bernoulli",
	"dessin en cours",
	"Auteur du script",
	"Licence GPL",
	"2010",
	"Lemniscate de Bernoulli",
	"*",
	[
	(PF_IMAGE,"img","image vide",None)
	],
	[],
	python_lemniscate,
        menu="<Image>/Filters/Render")

main()

Après ça il suffit d'enregistrer le fichier texte dans le dossier des scripts de Gimp, et de le rendre exécutable, pour avoir le script dans le Gimp, sous la forme d'un filtre de rendu.

Effet obtenuModifier

choix du pinceauModifier

Ce qui est remarquable à ce stade, c'est que l'effet obtenu va être très différent selon la forme et la taille du pinceau choisis. Par exemple, avec ns=6 et en prenant le pinceau en forme de poivron, on a ceci:

peinture sur toileModifier

Et avec une valeur plus raisonnable de 64 pour le nombre ns de sommets, on peut, une fois la lemniscate tracée (ici avec un pinceau "cercle flou de diamètre 8"), appliquer des filtres artistiques de Gimp (ici c'est le filtre toile, mais avec le filtre cubisme on a des résultats assez impressionnants):

ExerciceModifier

Essayer de reproduire cette image, issue du chapitre sur ImageJ, avec un filtre Python sous Gimp:

Remarque: Ce genre de technique permet aussi de créer des figures géométriques avec le logiciel Inkscape.