Arbeiten mit Transformationen in PS-Datei | Java
Transformieren Sie einen Inhalt im PS-Dokument
In diesem Artikel betrachten wir, wie man verschiedene Transformationen durchführt: Verschiebung, Skalierung, Drehung und Scherung auf einem zu PsDocument hinzugefügten Rechteckpfad.
Wir teilen ein Code-Snippet in mehrere Codeteile auf: den Anfang, das Ende und jede Transformation separat. Eine Transformation in PostScript erfolgt immer in einem Grafikzustand, der durch die Operatoren “gsave” und “grestore” gebunden ist. Daher gibt es in unserem PsDocument die Methoden “writeGraphicsSave()” und “writeGraphicsRestore()”. Zwischen diesen Methoden können wir beliebige Inhalte hinzufügen, einschließlich des Zustands verschachtelter Grafiken, und beliebige Transformationen oder Beschneidungen vornehmen. Diese Transformationen wirken sich nicht auf äußere Grafikzustände aus, wohl aber auf verschachtelte.
Wenn wir eine Transformation ohne die Methoden “writeGraphicsSave()” und “writeGraphicsRestore()” durchführen, führen wir sie im Grafikzustand der oberen Ebene und allen Inhalten durch das heißt in PsDocument wird dieser Transformation unterzogen.
Ein Algorithmus zum Festlegen einer Transformation für den Inhalt eines Dokuments von Grund auf umfasst die folgenden Schritte:
- Erstellen Sie einen Ausgabestream für die resultierende PS-Datei.
- Erstellen Sie PsSaveOptions.
- Erstellen Sie PsDocument mit dem bereits erstellten Ausgabestream und den Speicheroptionen.
- Speichern Sie einen Grafikstatus. Also haben wir einen neuen Grafikstatus erstellt, der vorherige Grafikstatus wurde in einen Grafikstatusstapel gelegt.
- Fügen Sie die erforderliche Transformation hinzu: Translation, Skalierung, Rotation, Scherung oder eine beliebige Kombination davon. In unserem Code zeigen wir den Einfluss jeder Transformationskomponente einzeln und am Ende jeweils drei.
- Fügen Sie den für die Transformation erforderlichen Inhalt hinzu. In unserem Fall haben wir java.awt.geom.Rectangle2D erstellt und es dann gefüllt. Wir haben vor allen Transformationen ein Rechteck erstellt und es nach jeder Transformation im aktuellen Grafikstatus einfach gefüllt.
- Stellen Sie den Grafikstatus wieder her, um zum vorherigen Zustand zurückzukehren, auf den sich die angewendeten Transformationen nicht auswirken. In unserem Fall handelt es sich um einen Grafikstatus der oberen Ebene.
In diesem Codeteil erstellen wir PsDocument aus einem Ausgabestream und PsSaveOptions, übersetzen den Grafikstatus der oberen Ebene in die Punkte 100,100, um das erste Rechteck zu versetzen, und erstellen schließlich das erste Rechteck:
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);
Hier legen wir die Farbe Orange als aktuelle Farbe für den Grafikstatus der oberen Ebene fest und füllen dieses Rechteck.
Die resultierende PS-Datei zeigt die erste Form, die sich im Grafikstatus der oberen Ebene befindet und keiner Transformation unterzogen wurde:
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/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Jetzt erstellen wir einen neuen Grafikstatus, der an 250 Punkten auf der X-Achse relativ zum Grafikstatus der oberen Ebene verschoben wird, und fügen zu diesem neuen Grafikstatus dasselbe Rechteck hinzu, das mit der Farbe Blau bemalt ist. Am Ende verlassen wir den aktuellen Grafikstatus und wechseln zum Grafikstatus der oberen Ebene:
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/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Übersetzen Sie den Grafikstatus der oberen Ebene, um die nächsten Rechtecke zu platzieren:
1//Displace on 200 to the bottom.
2document.translate(0, 200);
Hier erstellen wir einen Grafikstatus, der auf 0,5 x-Achse und 0,75 x Y-Achse skaliert wird, und fügen zu diesem neuen Grafikstatus dasselbe Rechteck hinzu, das mit der Farbe Rot bemalt ist. Am Ende verlassen wir den aktuellen Grafikstatus und wechseln zum Grafikstatus der oberen Ebene:
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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Übersetzen Sie den Grafikstatus der oberen Ebene, um die nächsten Rechtecke zu platzieren:
1//Displace upper level graphics state on 250 to the right.
2document.translate(250, 0);
Dann erstellen wir einen neuen Grafikzustand, der relativ zum Grafikzustand der oberen Ebene um 45 Grad im Uhrzeigersinn gedreht wird, und fügen diesem neuen Grafikzustand dasselbe Rechteck hinzu, das mit der Farbe Grün bemalt ist. Am Ende verlassen wir den aktuellen Grafikstatus und wechseln zum Grafikstatus der oberen Ebene:
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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Übersetzen Sie den Grafikstatus der oberen Ebene, um die nächsten Rechtecke in den leeren Bereich auf der Seite einzufügen.
1//Returns upper level graphics state back to the left and displace on 200 to the bottom.
2document.translate(-250, 200);
Dann erstellen wir einen neuen Grafikzustand, der geschert wird, und fügen diesem neuen Grafikzustand dasselbe Rechteck hinzu, das mit der Farbe Rosa bemalt ist. Am Ende verlassen wir den aktuellen Grafikstatus und wechseln zum Grafikstatus der oberen Ebene:
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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Übersetzen Sie den Grafikstatus der oberen Ebene, um die nächsten Rechtecke in den leeren Bereich auf der Seite einzufügen.
1//Displace upper level graphics state on 250 to the right.
2document.translate(250, 0);
Jetzt erstellen wir den letzten Grafikzustand, der einer komplexen Transformation unterzogen wird, die Übersetzungs-, Skalierungs- und Rotationskomponenten enthält, und fügen diesem neuen Grafikzustand dasselbe Rechteck hinzu, das mit der Farbe Aquamarin bemalt ist. Am Ende verlassen wir den aktuellen Grafikstatus und wechseln zum Grafikstatus der oberen Ebene:
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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Übersetzen Sie den Grafikstatus der oberen Ebene, um das letzte Rechteck im leeren Bereich der Seite zu platzieren:
1//Returns upper level graphics state back to the left and displace on 200 to the bottom.
2document.translate(-250, 200);
Das letzte gefüllte Rechteck, das wir wieder in den Grafikzustand der oberen Ebene eingefügt haben, zeigt, dass es keinen Transformationen der Grafikzustände der unteren Ebene und keinen Farbänderungen darin unterzogen wurde. Die orange Farbe verbleibt in der aktuellen Farbe:
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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Abschließend schließen wir die aktuelle Seite und speichern das Dokument:
1//Close current page
2document.closePage();
3
4//Save the document
5document.save();
6}
Siehe Arbeiten mit Transformationen im PS-Dokument in .NET.
Das Ergebnis der Ausführung dieses Codes ist das nächste
Sie können Beispiele und Datendateien herunterladen von GitHub.