Trabalhar com Transformações em PostScript | .NET

Transformar um conteúdo num Documento PS

Neste artigo, veremos como realizar diferentes transformações: translação, dimensionamento, rotação e cisalhamento num percurso retangular adicionado ao PsDocument.

Dividimos um trecho de código em vários trechos: o início, o fim e cada transformação em separado. Uma transformação em PostScript é sempre realizada num estado gráfico ligado aos operadores “gsave” e “grestore”. Assim, no nosso PsDocument, existem os métodos “WriteGraphicsSave()” e “WriteGraphicsRestore()”. Entre estes métodos, podemos adicionar qualquer conteúdo, incluindo estados gráficos aninhados, e realizar quaisquer transformações ou recortes. Estas transformações não afetarão os estados gráficos externos, mas afetarão os estados gráficos aninhados.

Se realizarmos uma transformação sem os métodos “WriteGraphicsSave()” e “WriteGraphicsRestore()”, esta será feita no estado gráfico do nível superior e todo o conteúdo em PsDocument será submetido a esta transformação.

Um algoritmo para definir qualquer transformação no conteúdo de um documento a partir do zero inclui os seguintes passos:

  1. Criar um fluxo de saída para o ficheiro PS resultante.
  2. Criar PsSaveOptions.
  3. Criar PsDocument com o fluxo de saída já criado e guardar as opções.
  4. Guardar um estado gráfico. Assim, criámos um novo estado gráfico e o estado gráfico anterior foi colocado numa pilha de estados gráficos.
  5. Adicione a transformação necessária: translação, escala, rotação, cisalhamento ou qualquer combinação das mesmas. No nosso código, mostramos a influência de cada componente da transformação em separado e, no final, 3 componentes de cada vez.
  6. Adicione o conteúdo necessário para a transformação. No nosso caso, criamos um retângulo GraphicsPath a partir do retângulo e preenchemo-lo. Criamos um retângulo antes de qualquer transformação e preenchemo-lo após cada transformação no estado gráfico atual.
  7. Restauramos o estado gráfico para voltar ao estado anterior, onde a(s) transformação(ões) aplicada(s) não afeta(m). No nosso caso, trata-se de um estado gráfico de nível superior.

Neste trecho de código, criamos o PsDocument a partir de um fluxo de saída e o PsSaveOptions, transladamos o estado gráfico de nível superior para os pontos 100 e 100 para deslocar o primeiro retângulo e, por fim, criamos o primeiro retângulo GraphicsPath a partir do retângulo.

 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));

Para Linux, MacOS e outros sistemas operativos não Windows, oferecemos a utilização do nosso pacote NuGet Aspose.Page.Drawing. Utiliza o backend Aspose.Drawing em vez da biblioteca de sistema System.Drawing.

Assim, importe o namespace Aspose.Page.Drawing em vez do System.Drawing. Nos excertos de código acima e seguintes, será utilizado Aspose.Page.Drawing.RectangleF em vez de System.Drawing.RectangleF, Aspose.Page.Drawing.Drawing2D.GraphicsPath em vez de System.Drawing.Drawing2D.GraphicsPath e assim por diante. Os nossos exemplos de código no GitHub contêm todas as substituições necessárias.

Aqui, definimos a cor Laranja como a pintura atual para o estado gráfico de nível superior e preenchemos este retângulo.

O ficheiro PS resultante demonstrará a primeira forma localizada no estado gráfico de nível superior e que não sofreu qualquer transformação.

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/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Agora, criamos um novo estado gráfico que será transladado em 250 pontos pelo eixo X em relação ao estado gráfico de nível superior e adicionamos a este novo estado gráfico o mesmo caminho retangular pintado com a cor Azul. No final, saímos do estado gráfico atual no estado gráfico de nível superior.

 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/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Traduza o estado dos gráficos de nível superior para colocar os retângulos seguintes.

1    //Displace on 200 to the bottom.
2    document.Translate(0, 200);

Aqui, criamos um estado gráfico que será dimensionado em 0,5 no eixo X e 0,75 no eixo Y e adicionamos a estes novos estados gráficos o mesmo percurso retangular pintado com a cor Vermelho. No final, saímos do estado gráfico atual para o estado gráfico de nível superior.

 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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Traduza o estado gráfico de nível superior para colocar os retângulos seguintes.

1    //Displace upper level graphics state on 250 to the right.
2    document.Translate(250, 0);

De seguida, criamos um novo estado gráfico que será rodado 45 graus no sentido dos ponteiros do relógio em relação ao estado gráfico de nível superior e adicionamos a este novo estado gráfico o mesmo caminho retangular pintado com a cor Verde. No final, saímos do estado gráfico atual no estado gráfico de nível superior.

 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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Traduza o estado gráfico de nível superior para colocar os retângulos seguintes no espaço em branco da página.

1    //Returns upper level graphics state back to the left and displace on 200 to the bottom.
2    document.Translate(-250, 200);

De seguida, criamos um novo estado gráfico que será distorcido e adicionamos a este novo estado gráfico o mesmo caminho retangular pintado com a cor Rosa. No final, saímos do estado gráfico atual no estado gráfico de nível superior.

 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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Traduza o estado gráfico de nível superior para colocar os retângulos seguintes no espaço em branco da página.

1    //Displace upper level graphics state on 250 to the right.
2    document.Translate(250, 0);

Agora, criamos o último estado gráfico que irá sofrer uma transformação complexa, contendo componentes de translação, escala e rotação, e adicionamos a este novo estado gráfico o mesmo caminho retangular pintado com a cor Aquamarine. No final, saímos do estado gráfico atual para o estado gráfico de nível superior.

 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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Traduza o estado gráfico de nível superior para colocar o último retângulo no espaço em branco da página.

1    //Returns upper level graphics state back to the left and displace on 200 to the bottom.
2    document.Translate(-250, 200);

O último retângulo preenchido que colocámos novamente no estado gráfico de nível superior mostra que não sofreu transformações nos estados gráficos do nível inferior nem alterações de cor. A cor laranja é a tinta atual restante.

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//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Por fim, fechamos a página atual e guardamos o documento.

1    //Close current page
2    document.ClosePage();
3
4    //Save the document
5    document.Save();
6}

Veja como trabalhar com transformações no documento PS em Java.


O resultado da execução deste código é o seguinte:

Transformações

Pode descarregar exemplos e ficheiros de dados do GitHub.

Have any questions about Aspose.Page?



Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.