Lavorare con le sfumature in PostScript | C++

Aggiungere un gradiente in un documento PS

In questo articolo, consideriamo i modi in cui un gradiente può essere utilizzato nei documenti PS.

Il gradiente è una transizione graduale da un colore all’altro. Viene utilizzato per rendere le immagini disegnate più realistiche. Poiché il gradiente è un tipo di pittura, è prevedibile che in C++ venga implementato come sottoclasse di System.Drawing.Brush. In realtà, la piattaforma C++ dispone di due pennelli di questo tipo:

Per impostare un pennello o un tratto in PsDocument, dobbiamo passare un oggetto della classe System.Drawing.Brush per un dipinto e un oggetto della classe System.Drawing.Pen per il tratto ai rispettivi metodi. La libreria Aspose.Page per C++ elabora tutte le sottoclassi di System.Drawing.Brush offerte dalla piattaforma C++. Queste sono System.Drawing.SolidBrush, System.Drawing.TextureBrush, System.Drawing.LinearGradientBrush, System.Drawing.PathGradientBrush e System.Drawing.HatchBrush. La classe System.Drawing.Pen non può essere estesa perché è sealed, ma contiene System.Drawing.Brush come proprietà e, pertanto, la libreria Aspose.Page per C++ può utilizzare un set completo di pennelli anche per disegnare linee e delineare forme e testo.

Per dipingere oggetti grafici con un gradiente nella libreria Aspose.Page per C++, è necessario creare System.Drawing.LinearGradientBrush o System.Drawing.PathGradientBrush e passarlo a SetPaint() o a uno dei metodi FillText() o FillAndStrokeText() che accettano System.Drawing.Brush come parametro.

Per delineare oggetti grafici con un gradiente nella libreria Aspose.Page per C++, è necessario creare System.Drawing.LinearGradientBrush o System.Drawing.PathGradientBrush, quindi creare System.Drawing.Pen con questo pennello e, infine, passarlo a SetStroke() o a uno dei metodi OutlineText() o FillAndStrokeText() che accetta System.Drawing.Pen come parametro.

Nell’esempio seguente mostriamo come riempire una forma e un testo e come delineare il testo con un gradiente.

Un algoritmo per dipingere oggetti grafici con un gradiente in un nuovo documento PS include i seguenti passaggi:

  1. Creare un flusso di output per il file PS risultante.
  2. Creare PsSaveOptions.
  3. Creare PsDocument con il flusso di output già creato e le opzioni di salvataggio.
  4. Creare il percorso grafico o il font necessari in base all’oggetto che si desidera riempire o delineare.
  5. Creare un oggetto di System.Drawing.LinearGradientBrush o System.Drawing.PathGradientBrush in base alla forma desiderata del gradiente.
  6. Impostare la trasformazione necessaria su questo pennello. 7. Imposta il pennello sfumato come tratto corrente in PsDocument.
  7. Riempi il tracciato grafico con il tratto corrente o riempi un testo. Se utilizziamo uno dei metodi per riempire il testo che accetta System.Drawing.Brush come parametro, il punto precedente può essere ignorato.
  8. Chiudi la pagina.
  9. Salva il documento.

Se desideriamo contornare (contornare) gli oggetti grafici con un gradiente invece degli ultimi 4 punti, ecco cosa fare:

  1. Crea l’oggetto System.Drawing.Pen con il pennello sfumato.

  2. Imposta questa penna come tratto corrente in PsDocument.

  3. Contorna il tracciato grafico con il tratto corrente o contorna il testo. Se utilizziamo uno dei metodi per contornare il testo che accetta System.Drawing.Pen come parametro, il punto precedente può essere ignorato.

  4. Chiudi la pagina.

  5. Salva il documento.

Offriamo 5 frammenti di codice che illustrano l’utilizzo di diversi gradienti.

In questo frammento di codice creiamo un gradiente lineare orizzontale da due colori, riempiamo un rettangolo, riempiamo un testo e tracciamo un contorno di testo con questo 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    }

Il risultato dell’esecuzione di questo codice è visualizzato come

Aggiungi sfumatura orizzontale

In questo frammento di codice creiamo una sfumatura lineare verticale da 5 colori e riempiamo un rettangolo con questa sfumatura.

 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    }

Ecco il risultato:

Aggiungi sfumatura verticale

In questo frammento di codice creiamo una sfumatura lineare diagonale da 2 colori e riempiamo un rettangolo con questa sfumatura.

 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    }

Ecco il risultato:

Aggiungi sfumatura diagonale

In questo frammento di codice creiamo una sfumatura radiale da 2 colori e riempiamo un cerchio con questa sfumatura.

 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}

Il risultato

Aggiungi immagine 1 sfumatura radiale

In questo frammento di codice creiamo una sfumatura radiale da 6 colori e riempiamo un rettangolo con questa sfumatura.

 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}

Il risultato

Aggiungi immagine 2 di Gradiente Radiale

Vedi come lavorare con il gradiente nei documenti PS in .NET o Java.

È possibile scaricare esempi e file di dati da GitHub.

Have any questions about Aspose.Page?



Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.