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:
- System.Drawing.LinearGradientBrush
- System.Drawing.PathGradientBrush
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:
- Creare un flusso di output per il file PS risultante.
- Creare PsSaveOptions.
- Creare PsDocument con il flusso di output già creato e le opzioni di salvataggio.
- Creare il percorso grafico o il font necessari in base all’oggetto che si desidera riempire o delineare.
- Creare un oggetto di System.Drawing.LinearGradientBrush o System.Drawing.PathGradientBrush in base alla forma desiderata del gradiente.
- Impostare la trasformazione necessaria su questo pennello. 7. Imposta il pennello sfumato come tratto corrente in PsDocument.
- 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.
- Chiudi la pagina.
- Salva il documento.
Se desideriamo contornare (contornare) gli oggetti grafici con un gradiente invece degli ultimi 4 punti, ecco cosa fare:
Crea l’oggetto System.Drawing.Pen con il pennello sfumato.
Imposta questa penna come tratto corrente in PsDocument.
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.
Chiudi la pagina.
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

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:

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:

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

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

È possibile scaricare esempi e file di dati da GitHub.