Trabalhar com Gradiente em PostScript | C++

Adicionar Gradiente em Documento PS

Neste artigo, consideramos as formas como um gradiente pode ser utilizado em documentos PS.

O gradiente é uma transição suave de uma cor para outra. É utilizado para tornar as imagens desenhadas mais realistas. Como o gradiente é um tipo de tinta, é esperado que em C++ seja implementado como uma subclasse de System.Drawing.Brush. Na verdade, a plataforma C++ possui dois destes pincéis:

Para definir uma tinta ou um traço em PsDocument, devemos passar um objeto da classe System.Drawing.Brush para uma pintura e um objeto da classe System.Drawing.Pen para o traço nos respetivos métodos. A biblioteca Aspose.Page para C++ processa todas as subclasses de System.Drawing.Brush oferecidas pela plataforma C++. São elas: System.Drawing.SolidBrush, System.Drawing.TextureBrush, System.Drawing.LinearGradientBrush, System.Drawing.PathGradientBrush e System.Drawing.HatchBrush. A classe System.Drawing.Pen não pode ser estendida porque está selada, mas contém System.Drawing.Brush como propriedade e, portanto, a biblioteca Aspose.Page para C++ também pode utilizar um conjunto completo de pincéis para desenhar linhas e contornar formas e texto.

Para pintar objetos gráficos com um gradiente na biblioteca Aspose.Page para C++, é necessário criar System.Drawing.LinearGradientBrush ou System.Drawing.PathGradientBrush e passá-los para SetPaint() ou um dos métodos FillText() ou FillAndStrokeText() que aceitam System.Drawing.Brush como parâmetro.

Para contornar os objetos gráficos com um gradiente na biblioteca Aspose.Page para C++, é necessário criar System.Drawing.LinearGradientBrush ou System.Drawing.PathGradientBrush, depois criar System.Drawing.Pen com este pincel e, por fim, passá-lo para SetStroke() ou um dos métodos OutlineText() ou FillAndStrokeText() que aceitam System.Drawing.Pen como parâmetro.

No exemplo abaixo, demonstramos como preencher uma forma e um texto e contorná-lo com um gradiente.

Um algoritmo para pintar objetos gráficos com um gradiente num novo documento PS inclui os seguintes passos:

  1. Crie um fluxo de saída para o ficheiro PS resultante.
  2. Crie PsSaveOptions.
  3. Crie PsDocument com o fluxo de saída já criado e as opções de guardar.
  4. Crie o caminho gráfico ou a fonte necessária, dependendo do objeto que iremos preencher ou contornar.
  5. Crie um objeto a partir de System.Drawing.LinearGradientBrush ou System.Drawing.PathGradientBrush, dependendo da forma desejada de um gradiente.
  6. Defina a transformação necessária neste pincel.
  7. Defina o pincel de gradiente como a pintura atual no PsDocument.
  8. Preencha o percurso gráfico com a pintura atual ou preencha um texto. Se utilizarmos um dos métodos de preenchimento de texto que aceita System.Drawing.Brush como parâmetro, o ponto anterior pode ser ignorado.
  9. Feche a página.
  10. Guarde o documento.

Se precisarmos de traçar (contornar) objetos gráficos com um gradiente em vez dos últimos 4 pontos, o seguinte será:

  1. Crie o objeto System.Drawing.Pen com o pincel de gradiente.

  2. Defina esta caneta como o traço atual no PsDocument.

  3. Contorne o percurso gráfico com o traço atual ou contorne o texto. Se utilizarmos um dos métodos de contorno de texto que aceita System.Drawing.Pen como parâmetro, o ponto anterior pode ser ignorado.

  4. Feche a página.

  5. Guarde o documento.

Disponibilizamos 5 excertos de código que demonstram a utilização de diferentes gradientes.

Neste excerto de código, criamos um gradiente linear horizontal a partir de duas cores, preenchemos um retângulo, preenchemos um texto e contornamos um texto com este gradiente.

 1    // The path to the documents directory.
 2    System::String dataDir = RunExamples::GetDataDir_WorkingWithGradient();
 3    
 4    //Create output stream for PostScript document
 5    {
 6        System::SharedPtr<System::IO::Stream> outPsStream = System::MakeObject<System::IO::FileStream>(dataDir + u"HorizontalGradient_outPS.ps", System::IO::FileMode::Create);
 7        // Clearing resources under 'using' statement
 8        System::Details::DisposeGuard<1> __dispose_guard_0({ outPsStream});
 9        // ------------------------------------------
10        
11        try
12        {
13            //Create save options with A4 size
14            System::SharedPtr<PsSaveOptions> options = System::MakeObject<PsSaveOptions>();
15            
16            // Create new 1-paged PS Document
17            System::SharedPtr<PsDocument> document = System::MakeObject<PsDocument>(outPsStream, options, false);
18            
19            float offsetX = 200.0f;
20            float offsetY = 100.0f;
21            float width = 200.0f;
22            float height = 100.0f;
23            
24            //Create graphics path from the first rectangle
25            System::SharedPtr<System::Drawing::Drawing2D::GraphicsPath> path = System::MakeObject<System::Drawing::Drawing2D::GraphicsPath>();
26            path->AddRectangle(System::Drawing::RectangleF(offsetX, offsetY, width, height));
27            
28            //Create linear gradient brush with rectangle as a bounds, start and end colors
29            System::SharedPtr<System::Drawing::Drawing2D::LinearGradientBrush> brush = System::MakeObject<System::Drawing::Drawing2D::LinearGradientBrush>(System::Drawing::RectangleF(0.0f, 0.0f, width, height), System::Drawing::Color::FromArgb(150, 0, 0, 0), System::Drawing::Color::FromArgb(50, 40, 128, 70), 0.f);
30            //Create a transform for brush. X and Y scale component must be equal to width and height of the rectangle correspondingly.
31            //Translation components are offsets of the rectangle
32            System::SharedPtr<System::Drawing::Drawing2D::Matrix> brushTransform = System::MakeObject<System::Drawing::Drawing2D::Matrix>(width, 0.0f, 0.0f, height, offsetX, offsetY);
33            //Set transform
34            brush->set_Transform(brushTransform);
35            
36            //Set paint
37            document->SetPaint(brush);
38            
39            //Fill the rectangle
40            document->Fill(path);
41            
42            //Fill text with gradient
43            System::SharedPtr<System::Drawing::Font> font = System::MakeObject<System::Drawing::Font>(u"Arial", 96.0f, System::Drawing::FontStyle::Bold);
44            document->FillAndStrokeText(u"ABC", font, 200.0f, 300.0f, brush, System::MakeObject<System::Drawing::Pen>(System::MakeObject<System::Drawing::SolidBrush>(System::Drawing::Color::get_Black()), 2.0f));
45            
46            //Set current stroke
47            document->SetStroke(System::MakeObject<System::Drawing::Pen>(brush, 5.0f));
48            //Outline text with gradient
49            document->OutlineText(u"ABC", font, 200.0f, 400.0f);
50            
51            //Close current page
52            document->ClosePage();
53            
54            //Save the document
55            document->Save();
56        }
57        catch(...)
58        {
59            __dispose_guard_0.SetCurrentException(std::current_exception());
60        }
61    }

O resultado da execução deste código é apresentado como

Adicionar Gradiente Horizontal

Neste excerto de código, criamos um gradiente linear vertical com 5 cores e preenchemos um retângulo com esse gradiente.

 1    // The path to the documents directory.
 2    System::String dataDir = RunExamples::GetDataDir_WorkingWithGradient();
 3    
 4    //Create output stream for PostScript document
 5    {
 6        System::SharedPtr<System::IO::Stream> outPsStream = System::MakeObject<System::IO::FileStream>(dataDir + u"VerticalGradient_outPS.ps", System::IO::FileMode::Create);
 7        // Clearing resources under 'using' statement
 8        System::Details::DisposeGuard<1> __dispose_guard_0({ outPsStream});
 9        // ------------------------------------------
10        
11        try
12        {
13            //Create save options with A4 size
14            System::SharedPtr<PsSaveOptions> options = System::MakeObject<PsSaveOptions>();
15            
16            // Create new 1-paged PS Document
17            System::SharedPtr<PsDocument> document = System::MakeObject<PsDocument>(outPsStream, options, false);
18            
19            float offsetX = 200.0f;
20            float offsetY = 100.0f;
21            float width = 200.0f;
22            float height = 100.0f;
23            
24            //Create graphics path from the first rectangle
25            System::SharedPtr<System::Drawing::Drawing2D::GraphicsPath> path = System::MakeObject<System::Drawing::Drawing2D::GraphicsPath>();
26            path->AddRectangle(System::Drawing::RectangleF(offsetX, offsetY, width, height));
27            
28            //Create an array of interpolation colors
29            System::ArrayPtr<System::Drawing::Color> colors = System::MakeArray<System::Drawing::Color>({System::Drawing::Color::get_Red(), System::Drawing::Color::get_Green(), System::Drawing::Color::get_Blue(), System::Drawing::Color::get_Orange(), System::Drawing::Color::get_DarkOliveGreen()});
30            System::ArrayPtr<float> positions = System::MakeArray<float>({0.0f, 0.1873f, 0.492f, 0.734f, 1.0f});
31            System::SharedPtr<System::Drawing::Drawing2D::ColorBlend> colorBlend = System::MakeObject<System::Drawing::Drawing2D::ColorBlend>();
32            colorBlend->set_Colors(colors);
33            colorBlend->set_Positions(positions);
34            
35            //Create linear gradient brush with rectangle as a bounds, start and end colors
36            System::SharedPtr<System::Drawing::Drawing2D::LinearGradientBrush> brush = System::MakeObject<System::Drawing::Drawing2D::LinearGradientBrush>(System::Drawing::RectangleF(0.0f, 0.0f, width, height), System::Drawing::Color::get_Beige(), System::Drawing::Color::get_DodgerBlue(), 0.f);
37            //Set interpolation colors
38            brush->set_InterpolationColors(colorBlend);
39            //Create a transform for brush. X and Y scale component must be equal to width and height of the rectangle correspondingly.
40            //Translation components are offsets of the rectangle
41            System::SharedPtr<System::Drawing::Drawing2D::Matrix> brushTransform = System::MakeObject<System::Drawing::Drawing2D::Matrix>(width, 0.0f, 0.0f, height, offsetX, offsetY);
42            //Rotate transform to get colors change in vertical direction from up to down
43            brushTransform->Rotate(90.0f);
44            //Set transform
45            brush->set_Transform(brushTransform);
46            
47            //Set paint
48            document->SetPaint(brush);
49            
50            //Fill the rectangle
51            document->Fill(path);
52            
53            //Close current page
54            document->ClosePage();
55            
56            //Save the document
57            document->Save();
58        }
59        catch(...)
60        {
61            __dispose_guard_0.SetCurrentException(std::current_exception());
62        }
63    }

Aqui está o resultado:

Adicionar Gradiente Vertical

Neste trecho de código, criamos um gradiente linear diagonal a partir de 2 cores e preenchemos um retângulo com esse gradiente.

 1    // The path to the documents directory.
 2    System::String dataDir = RunExamples::GetDataDir_WorkingWithGradient();
 3    
 4    //Create output stream for PostScript document
 5    {
 6        System::SharedPtr<System::IO::Stream> outPsStream = System::MakeObject<System::IO::FileStream>(dataDir + u"DiagonaGradient_outPS.ps", System::IO::FileMode::Create);
 7        // Clearing resources under 'using' statement
 8        System::Details::DisposeGuard<1> __dispose_guard_0({ outPsStream});
 9        // ------------------------------------------
10        
11        try
12        {
13            //Create save options with A4 size
14            System::SharedPtr<PsSaveOptions> options = System::MakeObject<PsSaveOptions>();
15            
16            // Create new 1-paged PS Document
17            System::SharedPtr<PsDocument> document = System::MakeObject<PsDocument>(outPsStream, options, false);
18            
19            float offsetX = 200.0f;
20            float offsetY = 100.0f;
21            float width = 200.0f;
22            float height = 100.0f;
23            
24            //Create graphics path from the first rectangle
25            System::SharedPtr<System::Drawing::Drawing2D::GraphicsPath> path = System::MakeObject<System::Drawing::Drawing2D::GraphicsPath>();
26            path->AddRectangle(System::Drawing::RectangleF(offsetX, offsetY, width, height));
27            
28            //Create linear gradient brush with rectangle as a bounds, start and end colors
29            System::SharedPtr<System::Drawing::Drawing2D::LinearGradientBrush> brush = System::MakeObject<System::Drawing::Drawing2D::LinearGradientBrush>(System::Drawing::RectangleF(0.0f, 0.0f, width, height), System::Drawing::Color::FromArgb(255, 255, 0, 0), System::Drawing::Color::FromArgb(255, 0, 0, 255), 0.f);
30            
31            //Create a transform for brush. X and Y scale component must be equal to width and height of the rectangle correspondingly.
32            //Translation components are offsets of the rectangle                
33            System::SharedPtr<System::Drawing::Drawing2D::Matrix> brushTransform = System::MakeObject<System::Drawing::Drawing2D::Matrix>(width, 0.0f, 0.0f, height, offsetX, offsetY);
34            //Rotate gradient, than scale and translate to get visible color transition in required rectangle
35            brushTransform->Rotate(-45.0f);
36            float hypotenuse = (float)System::Math::Sqrt(200 * 200 + 100 * 100);
37            float ratio = hypotenuse / 200;
38            brushTransform->Scale(-ratio, 1.0f);
39            brushTransform->Translate(100 / brushTransform->get_Elements()[0], 0.0f);
40            
41            //Set transform
42            brush->set_Transform(brushTransform);
43            
44            //Set paint
45            document->SetPaint(brush);
46            
47            //Fill the rectangle
48            document->Fill(path);
49            
50            //Close current page
51            document->ClosePage();
52            
53            //Save the document
54            document->Save();
55        }
56        catch(...)
57        {
58            __dispose_guard_0.SetCurrentException(std::current_exception());
59        }
60    }

Aqui está o resultado:

Adicionar Gradiente Diagonal

Neste trecho de código, criamos um gradiente radial de 2 cores e preenchemos um círculo com esse gradiente.

 1    // The path to the documents directory.
 2    System::String dataDir = RunExamples::GetDataDir_WorkingWithGradient();
 3    
 4    //Create output stream for PostScript document
 5    {
 6        System::SharedPtr<System::IO::Stream> outPsStream = System::MakeObject<System::IO::FileStream>(dataDir + u"RadialGradient1_outPS.ps", System::IO::FileMode::Create);
 7        // Clearing resources under 'using' statement
 8        System::Details::DisposeGuard<1> __dispose_guard_0({ outPsStream});
 9        // ------------------------------------------
10        
11        try
12        {
13            //Create save options with A4 size
14            System::SharedPtr<PsSaveOptions> options = System::MakeObject<PsSaveOptions>();
15            
16            // Create new 1-paged PS Document
17            System::SharedPtr<PsDocument> document = System::MakeObject<PsDocument>(outPsStream, options, false);
18            
19            float offsetX = 200.0f;
20            float offsetY = 100.0f;
21            float width = 200.0f;
22            float height = 200.0f;
23            
24            //Create graphics path from the rectangle bounds
25            System::Drawing::RectangleF bounds(offsetX, offsetY, width, height);
26            System::SharedPtr<System::Drawing::Drawing2D::GraphicsPath> path = System::MakeObject<System::Drawing::Drawing2D::GraphicsPath>();
27            path->AddEllipse(bounds);
28            
29            //Create and fill color blend object
30            System::ArrayPtr<System::Drawing::Color> colors = System::MakeArray<System::Drawing::Color>({System::Drawing::Color::get_White(), System::Drawing::Color::get_White(), System::Drawing::Color::get_Blue()});
31            System::ArrayPtr<float> positions = System::MakeArray<float>({0.0f, 0.2f, 1.0f});
32            System::SharedPtr<System::Drawing::Drawing2D::ColorBlend> colorBlend = System::MakeObject<System::Drawing::Drawing2D::ColorBlend>();
33            colorBlend->set_Colors(colors);
34            colorBlend->set_Positions(positions);
35            
36            System::SharedPtr<System::Drawing::Drawing2D::GraphicsPath> brushRect = System::MakeObject<System::Drawing::Drawing2D::GraphicsPath>();
37            brushRect->AddRectangle(System::Drawing::RectangleF(0.0f, 0.0f, width, height));
38            
39            //Create path gradient brush with rectangle as a bounds
40            System::SharedPtr<System::Drawing::Drawing2D::PathGradientBrush> brush = System::MakeObject<System::Drawing::Drawing2D::PathGradientBrush>(brushRect);
41            //Set interpolation colors
42            brush->set_InterpolationColors(colorBlend);
43            //Create a transform for brush. X and Y scale component must be equal to width and height of the rectangle correspondingly.
44            //Translation components are offsets of the rectangle
45            System::SharedPtr<System::Drawing::Drawing2D::Matrix> brushTransform = System::MakeObject<System::Drawing::Drawing2D::Matrix>(width, 0.0f, 0.0f, height, offsetX, offsetY);
46            //Set transform
47            brush->set_Transform(brushTransform);
48            
49            //Set paint
50            document->SetPaint(brush);
51            
52            //Fill the rectangle
53            document->Fill(path);
54            
55            //Close current page
56            document->ClosePage();
57            
58            //Save the document
59            document->Save();
60        }
61        catch(...)
62        {
63            __dispose_guard_0.SetCurrentException(std::current_exception());
64        }
65    }
66}

O resultado

Adicionar imagem de gradiente radial1

Neste trecho de código, criamos um gradiente radial a partir de 6 cores e preenchemos um retângulo com esse gradiente.

 1    // The path to the documents directory.
 2    System::String dataDir = RunExamples::GetDataDir_WorkingWithGradient();
 3    
 4    //Create output stream for PostScript document
 5    {
 6        System::SharedPtr<System::IO::Stream> outPsStream = System::MakeObject<System::IO::FileStream>(dataDir + u"RadialGradient2_outPS.ps", System::IO::FileMode::Create);
 7        // Clearing resources under 'using' statement
 8        System::Details::DisposeGuard<1> __dispose_guard_0({ outPsStream});
 9        // ------------------------------------------
10        
11        try
12        {
13            //Create save options with A4 size
14            System::SharedPtr<PsSaveOptions> options = System::MakeObject<PsSaveOptions>();
15            
16            // Create new 1-paged PS Document
17            System::SharedPtr<PsDocument> document = System::MakeObject<PsDocument>(outPsStream, options, false);
18            
19            float offsetX = 200.0f;
20            float offsetY = 100.0f;
21            float width = 200.0f;
22            float height = 200.0f;
23            
24            //Create graphics path from the rectangle bounds
25            System::Drawing::RectangleF bounds(offsetX, offsetY, width, height);
26            System::SharedPtr<System::Drawing::Drawing2D::GraphicsPath> path = System::MakeObject<System::Drawing::Drawing2D::GraphicsPath>();
27            path->AddRectangle(bounds);
28            
29            //Create and fill color blend object
30            System::ArrayPtr<System::Drawing::Color> colors = System::MakeArray<System::Drawing::Color>({System::Drawing::Color::get_Green(), System::Drawing::Color::get_Blue(), System::Drawing::Color::get_Black(), System::Drawing::Color::get_Yellow(), System::Drawing::Color::get_Beige(), System::Drawing::Color::get_Red()});
31            System::ArrayPtr<float> positions = System::MakeArray<float>({0.0f, 0.2f, 0.3f, 0.4f, 0.9f, 1.0f});
32            System::SharedPtr<System::Drawing::Drawing2D::ColorBlend> colorBlend = System::MakeObject<System::Drawing::Drawing2D::ColorBlend>();
33            colorBlend->set_Colors(colors);
34            colorBlend->set_Positions(positions);
35            
36            System::SharedPtr<System::Drawing::Drawing2D::GraphicsPath> brushRect = System::MakeObject<System::Drawing::Drawing2D::GraphicsPath>();
37            brushRect->AddRectangle(System::Drawing::RectangleF(0.0f, 0.0f, width, height));
38            
39            //Create path gradient brush with rectangle as a bounds
40            System::SharedPtr<System::Drawing::Drawing2D::PathGradientBrush> brush = System::MakeObject<System::Drawing::Drawing2D::PathGradientBrush>(brushRect);
41            //Set interpolation colors
42            brush->set_InterpolationColors(colorBlend);
43            //Create a transform for brush. X and Y scale component must be equal to width and height of the rectangle correspondingly.
44            //Translation components are offsets of the rectangle
45            System::SharedPtr<System::Drawing::Drawing2D::Matrix> brushTransform = System::MakeObject<System::Drawing::Drawing2D::Matrix>(width, 0.0f, 0.0f, height, offsetX, offsetY);
46            //Set transform
47            brush->set_Transform(brushTransform);
48            
49            //Set paint
50            document->SetPaint(brush);
51            
52            //Fill the rectangle
53            document->Fill(path);
54            
55            //Close current page
56            document->ClosePage();
57            
58            //Save the document
59            document->Save();
60        }
61        catch(...)
62        {
63            __dispose_guard_0.SetCurrentException(std::current_exception());
64        }
65    }
66}

O resultado

Adicionar imagem de Gradiente Radial2

Veja como trabalhar com gradiente em documentos PS em .NET ou Java.

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.