Работа с градиентом в PostScript | С++
Добавить градиент в документ PS
В этой статье мы рассмотрим способы использования градиента в документах PS.
Градиент – это плавный переход одного цвета в другой. Он используется для придания нарисованным изображениям большей реалистичности. Поскольку градиент — это своего рода краска, ожидается, что в C++ он реализован как подкласс System.Drawing.Brush. На самом деле на платформе C++ есть две такие кисти:
- System.Drawing.LinearGradientBrush
- System.Drawing.PathGradientBrush
Чтобы установить рисование или обводку в PsDocument, мы должны передать объект класса System.Drawing.Brush для рисования и объект System.Drawing.Pen для обводки в соответствующие методы. Библиотека Aspose.Page для C++ обрабатывает все подклассы System.Drawing.Brush, предлагаемые платформой C++. Это System.Drawing.SolidBrush, System.Drawing.TextureBrush, System.Drawing.LinearGradientBrush, System.Drawing.PathGradientBrush и *System.Drawing.HatchBrush *. Класс System.Drawing.Pen не может быть расширен, поскольку он запечатан, но он содержит System.Drawing.Brush в качестве свойства и, таким образом, библиотека Aspose.Page для C++ также может использовать полный набор кисти также для рисования линий и обрисовки фигур и текста.
Чтобы рисовать графические объекты градиентом в библиотеке Aspose.Page для C++, необходимо создать System.Drawing.LinearGradientBrush или System.Drawing.PathGradientBrush и передать его в SetPaint( ) или один из методов FillText() или FillAndStrokeText(), которые принимают System.Drawing.Brush в качестве параметра.
Чтобы обвести графические объекты градиентом в библиотеке Aspose.Page для C++, кто-то должен создать System.Drawing.LinearGradientBrush или System.Drawing.PathGradientBrush, а затем создать **System.Drawing.Pen ** с помощью этой кисти и, наконец, передайте ее SetStroke() или одному из методов OutlineText() или FillAndStrokeText(), который принимает System.Drawing.Pen в качестве параметра.
В примере ниже мы демонстрируем, как заполнить фигуру и текст и обвести текст градиентом.
Алгоритм закрашивания графических объектов градиентом в новом PS-документе включает следующие шаги:
- Создайте выходной поток для полученного PS-файла.
- Создайте PsSaveOptions.
- Создайте PsDocument с уже созданным потоком вывода и сохраните параметры.
- Создайте необходимый графический контур или шрифт в зависимости от того, какой объект мы собираемся заливать или обводить.
- Создайте объект System.Drawing.LinearGradientBrush или System.Drawing.PathGradientBrush в зависимости от желаемой формы градиента.
- Установите необходимую трансформацию этой кисти.
- Установите градиентную кисть в качестве текущей краски в PsDocument.
- Заполните графический контур текущей краской или заполните текст. Если мы воспользуемся одним из методов заливки текста, принимающим в качестве параметра System.Drawing.Brush, предыдущий пункт можно игнорировать.
- Закройте страницу.
- Сохраните документ.
Если нам нужно обводка (обводка) графических объектов градиентом вместо последних 4 точек, будет следующее:8. Создайте объект System.Drawing.Pen с помощью градиентной кисти.
Установите это перо в качестве текущего штриха в PsDocument.
Обведите графический путь текущей обводкой или обведите текст. Если мы используем один из методов выделения текста, который принимает System.Drawing.Pen в качестве параметра, предыдущую точку можно игнорировать.
Закройте страницу.
Сохраните документ.
Мы предлагаем 5 фрагментов кода, демонстрирующих использование различных градиентов.
В этом фрагменте кода мы создаем горизонтальный линейный градиент из двух цветов, заливаем прямоугольник, заливаем текст, обводим текст этим градиентом.
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 }
Результат запуска этого кода выглядит так:
В этом фрагменте кода мы создаем вертикальный линейный градиент из 5 цветов и заливаем этим градиентом прямоугольник.
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 }
Вот результат:
В этом фрагменте кода мы создаем диагональный линейный градиент из двух цветов и заливаем этим градиентом прямоугольник.
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 }
Вот результат:
В этом фрагменте кода мы создаем радиальный градиент из двух цветов и заполняем этим градиентом круг.
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}
Результат
В этом фрагменте кода мы создаем радиальный градиент из 6 цветов и заливаем этим градиентом прямоугольник.
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}
Результат
Вы можете загрузить примеры и файлы данных с сайта GitHub.