svg devzone

"I'll let you figure out
which one has been slow in supporting SVG." Tim Berners-Lee

Convertir un path Svg en java2D

Wed, 23 Dec

En cour d'écriture ...

Convertir un path Svg en java2D

Introduction

Dans le but de faire des animations à partir de fichiers SVG (en utilisant l'API Batik et donc Java2D ), j'ai chercher un moyen de pouvoir facilement convertir un path dessiner au préalable avec un outils tel Inkscape en code utilisable par mon application "Animation de SVG" (java).

Pas évident de créer directement des formes (shape) complexes en les calculant (j'ai pas de doctorat en math ...) !
Il me semblait donc bien plus facile de les dessiner avec un outil approprié, laissant plus de liberté à mon imagination.

Après avoir commencer à coder un "parseur" de chemin, je me suis rendu compte qu'il existait déjà ...
Et comme c'est bien connu : Rien ne sert de réinventer ... blablabla !".
On y avait pensé pour moi sous le bien nommé : Class AWTPathProducer

AWTPathProducer : Utilisation

Cette classe est vraiment très utile.
Elle permet de convertir un chaine de caractère définissant un "path" en un forme géométrique ( shape )utilisable par l'API batik.
C'est juste ce que je cherchais :)

Et comme Graphics2D sait très bien dessiner une forme (ex : g2.fill(Shape shape)), je n'ai "plus qu'a" (!!!) créer une animation à partir d'une liste de chaine de caratère (String) ...
faut juste faire tous les dessins avant !
1 an ou 2 pour une animation de type Cartoon de quelques minutes ... mais non je ferai de l'anim type manga (gloup).

Ouvrer votre Inkscape ...

... à l'onglet "nouveau dossier" et ... défoulez-vous !
"je l'aime bien ce chapitre ..."

C'est fait ... Vous avez votre graphique SVG prêt ?
Nous pouvons passer aux choses sérieuses.

Comment utiliser notre SVG

Notre application va traduire un seul path à la fois.
Et il y a beaucoup de chances que votre dessin en comporte plusieurs.

Plusieurs solutions viennent à l'esprit.

Nous pouvons tenter de réunir tous les chemins en un seul , c'est à dire avoir un seul attribut d="...".
Mais peu fiable et plutôt long à mettre en place (pas vraiment optimisé).

Nous pouvons également mettre tous les différents paths de notre graphique SVG dans un même fichier.
Et parcourir celui-ci ligne après ligne :

tant que différent de EOF
lire path
dessiner path

pourquoi pas ... !!!

La meilleure solution serait bien entendu de lire le fichier SVG en entier et de ne parser que les éléments path (path data).
Il faudra pour cela charger (load) notre fichier et les extraire l'un après l'autre.

Tant que différent de EOF
si element est de type path
alors dessiner element

Oui mais si nous avons mis par exemple un rectangle dans notre SVG ?
Pour l'instant nous allons l'ignorer.Mais il est à noter que Inkscape propose de convertir tout objet en chemin.

Autre petit désagrément lorsque nous créons un dessin "à main levée" avec Inkscape : il est plutôt verbose !!!
Nous allons utiliser en temps utile le génial outil de (écrit en python) Scour (je vous l'ai présenté dans une récente 'news').

Bon il est temps d'itérer comme dirant les développeurs agiles et codant notre première application qui affichera un seul path.

Notre appication (iteration1)

Elle est très simple : elle doit dessiner une forme géométrique.
Je ne vais donc pas entrer dans le détail.

public class Application extends JFrame{
	private static Shape shape = null;
	private boolean isSelected;

	
	public Application(Shape s){
		super("render svg path");
		this.shape = s;
		this.setSize(500,400);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		this.pack();
		//this.dispose();
		this.setVisible(true);
	}

	public void setShape(Shape shape) {
		this.shape = shape;
	}

	public static Shape getShape() {
		return shape;
	}
	
	public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.white);
        g2.draw(this.shape);  
        
    }

}
		

Pour tester votre code (et vous amusez avec ... mais trop longtemps hein ! ... ce serait suspect!), ajouter une porte d'entrée pour la JVM grâce la fameuse static void main.

		
public static void main(String[] mesArguments){
	Application app = new Application(new Rectangle(100, 100, 400, 400));
}
		
		

Remarque

Prenez l'habitude de tester votre code au fur et à mesure et non pas à la fin.
C'est un des bénéfices de l'utilisation de "méthodes itératives". (notez les guillemets qui me dédouane des commentaires de puristes 'Agiles' et autres 'Unified Process').

Que cette remarque ne nous éloigne pas de notre objectif : lire des svg path depuis un fichier source pour l'afficher dans une application Java2D (à loisir de le transformer à nouveau en Svg Graphics 2D ...).
L'intérêt ou non de ces applications est ici hors sujet !

Création de notre forme géométrique

Pour rappel nous avons besoin à partir d'une simple chaîne de caractères de créer une forme géométrique utilisable par l'API 2D.
Et ainsi de passer cette 'shape' (forme) en tant qu'argument à notre constructeur d'Apllication.

Pour cela, je prends un des 'chemins' dessinés à l'aide d'inkscape que je sauvegarde en dur dans un objet String :

		
String monPath = ""M 242,272.10595 C 242,263.67478 243.74404,247.27669 ...etc";
		
		

Il ne reste plus qu'à transformer cette chaine en forme géométrique.
Bref on a rien à faire puique AWTPathProducer va tout faire pour nous à l'aide de la méthode createShape.

Notez les différents arguments qu'il nous faut passer à cette méthode :

  • r - The reader used to read the path specification
  • wr - The winding rule to use for creating the path.

En cherchant un peu quels sont les 'readers' en java, on a justement un lecteur de chaîne à notre disposition (class StringReader ).

Le code est très simple également ...

shape = AWTPathProducer.createShape(new StringReader(pathString), GeneralPath.WIND_EVEN_ODD);

Le premier argument est notre reader; Le second est le rôle utilisé (fill-rules properties).
Il utilise un algorithme the winding number algorithm.

Articles

svg-developers at yahoo group svg

Re: SVG in html5

Yes I want to understand how much is expected from an editing tool which does the validation and highlightling of all the tags and attributes and provides...

... lire la suite