Arbeiten mit Transformationen in PostScript | .NET
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, versetzen wir sie in den Grafikzustand der oberen Ebene und alle Inhalte, die sich in PsDocument befinden, werden 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 aus dem Rechteck ein Rechteck GraphicsPath 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 GraphicsPath aus dem Rechteck.
1//Create an output stream for PostScript document
2using (Stream outPsStream = new FileStream(dataDir + "Transformations_outPS.ps", FileMode.Create))
3{
4 //Create save options with default values
5 PsSaveOptions options = new PsSaveOptions();
6
7 // Create new 1-paged PS Document
8 PsDocument document = new PsDocument(outPsStream, options, false);
9
10 document.Translate(100, 100);
11
12 //Create graphics path from the rectangle
13 GraphicsPath path = new GraphicsPath();
14 path.AddRectangle(new RectangleF(0, 0, 150, 100));
Für Linux, MacOS und andere Nicht-Windows-Betriebssysteme bieten wir die Verwendung unseres Nuget-Pakets Aspose.Page.Drawing an. Es verwendet das Aspose.Drawing-Backend anstelle der System.Drawing-Systembibliothek.
Importieren Sie also den Namensraum Aspose.Page.Drawing anstelle des Namensraums System.Drawing. In den obigen und den folgenden Codeausschnitten wird Aspose.Page.Drawing.RectangleF anstelle von System.Drawing.RectangleF verwendet. Aspose.Page.Drawing.Drawing2D.GraphicsPath wird anstelle von System.Drawing.Drawing2D.GraphicsPath usw. verwendet. Unsere Codebeispiele auf GitHub enthalten alle notwendigen Ersetzungen.
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 Grafikzustand der oberen Ebene befindet und keiner Transformation unterzogen wurde.
1////////////////////////////////////// No transformations ///////////////////////////////////////////////////////////////
2 //Set a paint in graphics state on upper level
3 document.SetPaint(new SolidBrush(Color.Orange));
4
5 //Fill the first rectangle that is on on the upper-level graphics state and that is without any transformations.
6 document.Fill(path);
7/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Jetzt erstellen wir einen neuen Grafikzustand, der an 250 Punkten auf der X-Achse relativ zum Grafikzustand der oberen Ebene verschoben wird, und fügen diesem neuen Grafikzustand den gleichen rechteckigen Pfad hinzu, der mit der Farbe Blau bemalt ist. Am Ende verlassen wir den aktuellen Grafikstatus und wechseln zum Grafikstatus der oberen Ebene.
1////////////////////////////////////// Translation //////////////////////////////////////////////////////////////////////
2
3 //Save the graphics state in order to return back to this state after transformation
4 document.WriteGraphicsSave();
5
6 //Displace current graphics state on 250 to the right. So we add translation component to the current transformation.
7 document.Translate(250, 0);
8
9 //Set the paint in the current graphics state
10 document.SetPaint(new SolidBrush(Color.Blue));
11
12 //Fill the second rectangle in the current graphics state (has translation transformation)
13 document.Fill(path);
14
15 //Restore the graphics state to the previus (upper) level
16 document.WriteGraphicsRestore();
17/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Übersetzen Sie den Grafikstatus der oberen Ebene, um die nächsten Rechtecke zu platzieren.
1 //Displace on 200 to the bottom.
2 document.Translate(0, 200);
Hier erstellen wir einen Grafikzustand, der auf 0,5 auf der X-Achse und 0,75 auf der Y-Achse skaliert wird, und fügen zu diesem neuen Grafikzustand den gleichen rechteckigen Pfad hinzu, der 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
3 document.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.
6 document.Scale(0.5f, 0.75f);
7
8 //Set the paint in the current graphics state
9 document.SetPaint(new SolidBrush(Color.Red));
10
11 //Fill the third rectangle in the current graphics state (has scale transformation)
12 document.Fill(path);
13
14 //Restore the graphics state to the previus (upper) level
15 document.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.
2 document.Translate(250, 0);
Dann erstellen wir einen neuen Grafikstatus, der relativ zum Grafikstatus der oberen Ebene um 45 Grad im Uhrzeigersinn gedreht wird, und fügen diesem neuen Grafikstatus denselben rechteckigen Pfad hinzu, der 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 the graphics state in order to return back to this state after transformation
3 document.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.
6 document.Rotate(45));
7
8 //Set the paint in the current graphics state
9 document.SetPaint(new SolidBrush(Color.Green));
10
11 //Fill the fourth rectangle in the current graphics state (has rotation transformation)
12 document.Fill(path);
13
14 //Restore the graphics state to the previus (upper) level
15 document.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.
2 document.Translate(-250, 200);
Dann erstellen wir einen neuen Grafikzustand, der geschert wird, und fügen diesem neuen Grafikzustand den gleichen rechteckigen Pfad hinzu, der mit der Farbe Rosa bemalt ist. Am Ende verlassen wir den aktuellen Grafikstatus und wechseln zum Grafikstatus der oberen Ebene.
1////////////////////////////////////// Shearing //////////////////////////////////////////////////////////////////////
2 //Save the graphics state in order to return back to this state after transformation
3 document.WriteGraphicsSave();
4
5 //Shear current graphics state. So we add shear component to the current transformation.
6 document.Shear(0.1f, 0.2f);
7
8 //Set the paint in the current graphics state
9 document.SetPaint(new SolidBrush(Color.Pink));
10
11 //Fill the fifth rectangle in the current graphics state (has shear transformation)
12 document.Fill(path);
13
14 //Restore the graphics state to the previus (upper) level
15 document.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.
2 document.Translate(250, 0);
Jetzt erstellen wir den letzten Grafikzustand, der einer komplexen Transformation mit Übersetzungs-, Skalierungs- und Rotationskomponenten unterzogen wird, und fügen diesem neuen Grafikzustand den gleichen rechteckigen Pfad hinzu, der 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 the graphics state in order to return back to this state after transformation
3 document.WriteGraphicsSave();
4
5 //Transform current graphics state with complex transformation. So we add translation, scale and rotation components to the current transformation.
6 document.Transform(new Matrix(1.2f, -0.965925f, 0.258819f, 1.5f, 0f, 50));
7
8 //Set the paint in the current graphics state
9 document.SetPaint(new SolidBrush(Color.Aquamarine));
10
11 //Fill the sixth rectangle in the current graphics state (has complex transformation)
12 document.Fill(path);
13
14 //Restore the graphics state to the previus (upper) level
15 document.WriteGraphicsRestore();
16//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Übersetzen Sie den Grafikstatus der oberen Ebene, um das letzte Rechteck in den leeren Bereich der Seite zu platzieren.
1 //Returns upper level graphics state back to the left and displace on 200 to the bottom.
2 document.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 ist die aktuelle 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)
4 document.Fill(path);
5//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Abschließend schließen wir die aktuelle Seite und speichern das Dokument.
1 //Close current page
2 document.ClosePage();
3
4 //Save the document
5 document.Save();
6}
Siehe Arbeiten mit Transformationen im PS-Dokument in Java.
Das Ergebnis der Ausführung dieses Codes ist das nächste
Sie können Beispiele und Datendateien herunterladen von GitHub.