Travailler avec des transformationsdans PS | Java
Transformer un contenu dans un document PS
Dans cet article, nous examinons comment effectuer différentes transformations : translation, mise à l’échelle, rotation et cisaillement sur un chemin rectangulaire ajouté à PsDocument.
Nous divisons un extrait de code en plusieurs morceaux de code : le début, la fin et chaque transformation séparément. Une transformation en PostScript est toujours effectuée dans un état graphique lié par les opérateurs “gsave” et “grestore”. Par conséquent, dans notre PsDocument, il existe des méthodes “writeGraphicsSave()” et “writeGraphicsRestore()”. Entre ces méthodes, nous pouvons ajouter n’importe quel contenu, y compris l’état graphique imbriqué, et effectuer des transformations ou des découpages. Ces transformations n’affecteront pas les états graphiques externes mais le feront sur ceux imbriqués.
Si nous effectuons une transformation sans les méthodes “writeGraphicsSave()” et “writeGraphicsRestore()” nous la faisons dans l’état graphique du niveau supérieur et tout le contenu qui se trouve dans PsDocument subira cette transformation.
Un algorithme permettant de définir toute transformation sur le contenu d’un document à partir de zéro comprend les étapes suivantes :
- Créez un flux de sortie pour le fichier PS résultant.
- Créez PsSaveOptions.
- Créez PsDocument avec le flux de sortie déjà créé et enregistrez les options.
- Enregistrez un état graphique. Nous avons donc créé un nouvel état graphique, l’état graphique précédent a été mis dans une pile d’états graphiques.
- Ajoutez la transformation nécessaire : translation, échelle, rotation, cisaillement ou toute combinaison de celles-ci. Dans notre code, nous montrons l’influence de chaque composant de transformation séparément et 3 à la fois au final.
- Ajoutez le contenu nécessaire à la transformation. Dans notre cas, nous avons créé java.awt.geom.Rectangle2D puis l’avons rempli. Nous avons créé un rectangle avant toute transformation et l’avons simplement rempli après chaque transformation dans l’état graphique actuel.
- Restaurez l’état graphique pour revenir à l’état précédent où les transformations appliquées n’affectent pas. Dans notre cas, il s’agit d’un état graphique de niveau supérieur.
Dans ce morceau de code, nous créons PsDocument à partir d’un flux de sortie et de PsSaveOptions, traduisons l’état graphique de niveau supérieur en points 100 100 afin de décaler le premier rectangle, et enfin créons le premier rectangle :
1//Create an output stream for PostScript document
2FileOutputStream outPsStream = new FileOutputStream(dataDir + "Tranformations_outPS.ps");
3//Create a save options with A4 size
4PsSaveOptions options = new PsSaveOptions();
5
6// Create new PS Document with the page opened
7PsDocument document = new PsDocument(outPsStream, options, false);
8
9document.translate(100, 100);
10
11//Create a rectangle
12Shape shape = new Rectangle2D.Float(0, 0, 150, 100);
Ici, nous définissons la couleur Orange comme peinture actuelle pour l’état graphique de niveau supérieur et remplissons ce rectangle.
Le fichier PS résultant montrera la première forme située dans l’état graphique de niveau supérieur et qui n’a subi aucune transformation :
1////////////////////////////////////// No transformations ///////////////////////////////////////////////////////////////
2//Set paint in graphics state on upper level
3document.setPaint(Color.ORANGE);
4
5//Fill the first rectangle that is on on upper level graphics state and that is without any transformations.
6document.fill(shape);
7/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Nous créons maintenant un nouvel état graphique qui sera traduit sur 250 points par l’axe X par rapport à l’état graphique de niveau supérieur et ajoutons à ce nouvel état graphique le même rectangle peint avec la couleur Bleu. Au final, on sort de l’état graphique actuel sur l’état graphique de niveau supérieur :
1////////////////////////////////////// Translation //////////////////////////////////////////////////////////////////////
2//Save graphics state in order to return back to this state after transformation
3document.writeGraphicsSave();
4
5//Displace current graphics state on 250 to the right. So we add translation component to the current transformation.
6document.translate(250, 0);
7
8//Set paint in the current graphics state
9document.setPaint(Color.BLUE);
10
11//Fill the second rectangle in the current graphics state (has translation transformation)
12document.fill(shape);
13
14//Restore graphics state to the previus (upper) level
15document.writeGraphicsRestore();
16/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Traduisez l’état graphique de niveau supérieur afin de mettre les rectangles suivants :
1//Displace on 200 to the bottom.
2document.translate(0, 200);
Ici, nous créons un état graphique qui sera mis à l’échelle sur 0,5 par axe X et 0,75 par axe Y et ajoutons à ce nouvel état graphique le même rectangle peint avec la couleur Rouge. Au final, on sort de l’état graphique actuel sur l’état graphique de niveau supérieur :
1////////////////////////////////////// Scaling //////////////////////////////////////////////////////////////////////////
2//Save the graphics state in order to return back to this state after transformation
3document.writeGraphicsSave();
4
5//Scale current graphics state on 0.5 in X axis and on 0.75f in Y axis. So we add scale component to the current transformation.
6document.scale(0.5f, 0.75f);
7
8//Set paint in the current graphics state
9document.setPaint(Color.RED);
10
11//Fill the third rectangle in the current graphics state (has scale transformation)
12document.fill(shape);
13
14//Restore graphics state to the previus (upper) level
15document.writeGraphicsRestore();
16//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Traduisez l’état graphique de niveau supérieur afin de mettre les rectangles suivants :
1//Displace upper level graphics state on 250 to the right.
2document.translate(250, 0);
Ensuite, nous créons un nouvel état graphique qui pivotera de 45 degrés dans le sens des aiguilles d’une montre par rapport à l’état graphique de niveau supérieur et ajoutons à ce nouvel état graphique le même rectangle peint avec la couleur Vert. Au final, on sort de l’état graphique actuel sur l’état graphique de niveau supérieur :
1////////////////////////////////////// Rotation //////////////////////////////////////////////////////////////////////
2//Save graphics state in order to return back to this state after transformation
3document.writeGraphicsSave();
4
5//Rotate current graphics state on 45 degrees around origin of current graphics state (350, 300). So we add rotation component to the current transformation.
6document.rotate(45);
7
8//Set paint in the current graphics state
9document.setPaint(Color.GREEN);
10
11//Fill the fourth rectangle in the current graphics state (has rotation transformation)
12document.fill(shape);
13
14//Restore graphics state to the previus (upper) level
15document.writeGraphicsRestore();
16//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Traduisez l’état graphique de niveau supérieur afin de placer les rectangles suivants dans l’espace vide de la page.
1//Returns upper level graphics state back to the left and displace on 200 to the bottom.
2document.translate(-250, 200);
Ensuite, nous créons un nouvel état graphique qui sera cisaillé et ajoutons à ce nouvel état graphique le même rectangle peint avec la couleur Rose. Au final, on sort de l’état graphique actuel sur l’état graphique de niveau supérieur :
1////////////////////////////////////// Shearing //////////////////////////////////////////////////////////////////////
2//Save graphics state in order to return back to this state after transformation
3document.writeGraphicsSave();
4
5//Shear current graphics state. So we add shear component to the current transformation.
6document.shear(0.1f, 0.2f);
7
8//Set paint in the current graphics state
9document.setPaint(new Color(255,192,203));
10
11//Fill the fifth rectangle in the current graphics state (has shear transformation)
12document.fill(shape);
13
14//Restore graphics state to the previous (upper) level
15document.writeGraphicsRestore();
16//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Traduisez l’état graphique de niveau supérieur afin de placer les rectangles suivants dans l’espace vide de la page.
1//Displace upper level graphics state on 250 to the right.
2document.translate(250, 0);
Nous créons maintenant le dernier état graphique qui sera soumis à une transformation complexe contenant des composants de translation, de mise à l’échelle et de rotation et ajoutons à ce nouvel état graphique le même rectangle peint avec la couleur Aigue-marine. Au final, on sort de l’état graphique actuel sur l’état graphique de niveau supérieur :
1////////////////////////////////////// Complex transformation ////////////////////////////////////////////////////////
2//Save graphics state in order to return back to this state after transformation
3document.writeGraphicsSave();
4
5//Transform current graphics state with complex transformation. So we add translation, scale and rotation components to the current transformation.
6document.transform(new AffineTransform(1.2f, -0.965925f, 0.258819f, 1.5f, 0f, 50));
7
8//Set paint in the current graphics state
9document.setPaint(new Color(127,255,212));
10
11//Fill the sixth rectangle in the current graphics state (has complex transformation)
12document.fill(shape);
13
14//Restore graphics state to the previus (upper) level
15document.writeGraphicsRestore();
16//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Traduisez l’état graphique de niveau supérieur afin de placer le dernier rectangle dans l’espace vide de la page :
1//Returns upper level graphics state back to the left and displace on 200 to the bottom.
2document.translate(-250, 200);
Le dernier rectangle rempli que l’on a remis dans l’état graphique de niveau supérieur montre qu’il n’a pas subi de transformations d’états graphiques de niveau inférieur et de changement de couleurs dans celui-ci. La couleur orange est celle de la peinture actuelle :
1////////////////////////////////////// Again no transformation ////////////////////////////////////////////////////////
2//Demonstrates that current graphics state's color is orange that was set up at the beginning of the code.
3//Fill the seventh rectangle in the current graphics state (has no transformation)
4document.fill(path);
5//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Enfin, nous fermons la page actuelle et enregistrons le document :
1//Close current page
2document.closePage();
3
4//Save the document
5document.save();
6}
Voir comment travailler avec des transformations dans un document PS dans .NET.
Le résultat de l’exécution de ce code est le suivant
Vous pouvez télécharger des exemples et des fichiers de données à partir de GitHub.