Использование графических утилит XPS | С++
Как легко создавать простые фигуры в XPS
Спецификация XPS определяет графические примитивные элементы, которые можно использовать для создания любых сложных фигур. Aspose.Page для C++ предоставляет классы, инкапсулирующие эти элементы. Однако их использование может быть немного утомительным, когда вам нужно создавать даже относительно простые фигуры, такие как круговой сектор или сегмент, или правильный n-угольник, вписанный в окружность или описанный вокруг нее. Даже рисование круга или эллипса не так просто, как могло бы и, вероятно, должно быть. Вот почему Aspose.Page дополнительно предоставляет набор методов-утилитов, которые, скорее всего, сэкономят ваше время при выполнении таких задач.
В следующем примере мы используем все доступные утилиты для работы с фигурами. Обратите внимание, что все они возвращают объект XpsPathGeometry, который затем можно использовать для построения XPS-путей. И для этих путей можно указать свойства внешнего вида — кисти, узор обводки, непрозрачность и т. д.
1 // ExStart:UsingShapeUtils
2 // For complete examples and data files, please go to https://github.com/aspose-page/Aspose.Page-for-C
3 // The path to the documents directory.
4 System::String dataDir = RunExamples::GetDataDir_WorkingWithShapes();
5 // Create new XPS Document
6 {
7 System::SharedPtr<XpsDocument> doc = System::MakeObject<XpsDocument>();
8 // Clearing resources under 'using' statement
9 System::Details::DisposeGuard<1> __dispose_guard_0({ doc});
10 // ------------------------------------------
11
12 try
13 {
14 // Set first page's size.
15 doc->get_Page()->set_Width(650.f);
16 doc->get_Page()->set_Height(240.f);
17
18 // Draw a circle with center (120, 120) and radius 100.
19 System::SharedPtr<XpsPath> path = doc->CreatePath(doc->get_Utils()->CreateCircle(System::Drawing::PointF(120.f, 120.f), 100.f));
20 path->set_Fill(doc->CreateSolidColorBrush(System::Drawing::Color::get_Green()));
21 doc->Add<System::SharedPtr<XpsPath>>(path);
22
23 // Inscribe a regular pentagon in the circle.
24 path = doc->CreatePath(doc->get_Utils()->CreateRegularInscribedNGon(5, System::Drawing::PointF(120.f, 120.f), 100.f));
25 path->set_Fill(doc->CreateSolidColorBrush(System::Drawing::Color::get_Red()));
26 doc->Add<System::SharedPtr<XpsPath>>(path);
27
28 // Circumscribe a regular hexagon around the circle.
29 path = doc->CreatePath(doc->get_Utils()->CreateRegularCircumscribedNGon(6, System::Drawing::PointF(120.f, 120.f), 100.f));
30 path->set_Stroke(doc->CreateSolidColorBrush(System::Drawing::Color::get_Magenta()));
31 path->set_StrokeThickness(3.f);
32 doc->Add<System::SharedPtr<XpsPath>>(path);
33
34 // Draw a sector of the circle centered at (340, 120), starting at -45 degrees and ending at +45 degrees.
35 path = doc->CreatePath(doc->get_Utils()->CreatePieSlice(System::Drawing::PointF(340.f, 120.f), 100.f, -45.f, 45.f));
36 path->set_Stroke(doc->CreateSolidColorBrush(System::Drawing::Color::get_Red()));
37 path->set_StrokeThickness(5.f);
38 doc->Add<System::SharedPtr<XpsPath>>(path);
39
40 // Draw a segment of the circle centered at (340, 120), starting at -45 degrees and ending at +45 degrees.
41 path = doc->CreatePath(doc->get_Utils()->CreateCircularSegment(System::Drawing::PointF(340.f, 120.f), 100.f, -45.f, 45.f));
42 path->set_Fill(doc->CreateSolidColorBrush(System::Drawing::Color::get_Black()));
43 doc->Add<System::SharedPtr<XpsPath>>(path);
44
45 // Draw a rectangle with the top left vertex (530, 20), width 100 units and height 200 units.
46 path = doc->CreatePath(doc->get_Utils()->CreateRectangle(System::Drawing::RectangleF(530.f, 20.f, 100.f, 200.f)));
47 path->set_Stroke(doc->CreateSolidColorBrush(System::Drawing::Color::get_Red()));
48 doc->Add<System::SharedPtr<XpsPath>>(path);
49
50 // Draw an ellipse with center (580, 120) and radii 50 and 100.
51 path = doc->CreatePath(doc->get_Utils()->CreateEllipse(System::Drawing::PointF(580.f, 120.f), 50.f, 100.f));
52 path->set_Fill(doc->CreateSolidColorBrush(System::Drawing::Color::get_Yellow()));
53 doc->Add<System::SharedPtr<XpsPath>>(path);
54
55 doc->Save(dataDir + u"UseShapeUtilsXPS_out.xps");
56 }
57 catch(...)
58 {
59 __dispose_guard_0.SetCurrentException(std::current_exception());
60 }
61 }
62 // ExEnd:UsingShapeUtils
Начинаем с нового документа XPS, затем настраиваем размер первой страницы. Первая фигура, которую мы размещаем на странице, — это круг (заданный его центром и радиусом), заполненный сплошным зеленым цветом. Затем мы вписываем в этот круг незаполненный красный правильный пятиугольник. Затем следует описанный правильный шестиугольник, заштрихованный пурпурным цветом.
Справа мы сначала рисуем красный круговой сектор (или «кусок пирога») между -45 и +45 градусами, а затем черный круговой сегмент с теми же параметрами над сектором.
Последняя часть рисунка состоит из красного прямоугольника (заданного верхней левой вершиной и размерами) и желтого эллипса (заданного центром и радиусами), вписанного в прямоугольник. Здесь мы управляем надписью «вручную».
Вот что мы должны увидеть в сохраненном файле XPS:
Как легко добавить изображение на страницу XPS
С примитивами, определенными спецификацией XPS, добавление изображения на страницу состоит из двух шагов:
- Добавление прямоугольного пути, который вы хотите заполнить изображением;
- Установка кисти изображения для пути, где вам нужно указать область просмотра и область просмотра. Как правило, вам нужно знать разрешение и размер в пикселях вашего изображения, чтобы точно указать первые два параметра.
Но к счастью, среди графических утилит XPS есть удобный метод API Aspose.Page для C++, который может сделать всю (почти) работу за вас. Он также предлагает вам различные режимы подгонки. Давайте рассмотрим пример ниже:
1 // ExStart:UsingImageUtils
2 // For complete examples and data files, please go to https://github.com/aspose-page/Aspose.Page-for-C
3 // The path to the documents directory.
4 System::String dataDir = RunExamples::GetDataDir_WorkingWithImages();
5 // Create new XPS Document
6 {
7 System::SharedPtr<XpsDocument> doc = System::MakeObject<XpsDocument>();
8 // Clearing resources under 'using' statement
9 System::Details::DisposeGuard<1> __dispose_guard_0({ doc});
10 // ------------------------------------------
11
12 try
13 {
14 // Set first page's size.
15 doc->get_Page()->set_Width(540.f);
16 doc->get_Page()->set_Height(220.f);
17
18 // Draw the image box.
19 System::Drawing::RectangleF imageBox(10.f, 10.f, 200.f, 200.f);
20 System::SharedPtr<XpsPath> path = doc->AddPath(doc->get_Utils()->CreateRectangle(imageBox));
21 path->set_Stroke(doc->CreateSolidColorBrush(System::Drawing::Color::get_Black()));
22 // Add an image to fit width.
23 path = doc->get_Utils()->CreateImage(dataDir + u"R08LN_NN.jpg", imageBox, Aspose::Page::XPS::ImageMode::FitToWidth);
24 // Prevent tiling.
25 (System::ExplicitCast<Aspose::Page::XPS::XpsModel::XpsImageBrush>(path->get_Fill()))->set_TileMode(Aspose::Page::XPS::XpsModel::XpsTileMode::None);
26 doc->Add<System::SharedPtr<XpsPath>>(path);
27
28 // Add an image to fit width.
29 doc->Add<System::SharedPtr<XpsPath>>(doc->get_Utils()->CreateImage(dataDir + u"R08LN_NN.jpg", System::Drawing::RectangleF(220.f, 10.f, 200.f, 100.f), Aspose::Page::XPS::ImageMode::FitToHeight));
30
31 // Add an image to fit width.
32 doc->Add<System::SharedPtr<XpsPath>>(doc->get_Utils()->CreateImage(dataDir + u"R08LN_NN.jpg", System::Drawing::RectangleF(430.f, 10.f, 100.f, 200.f), Aspose::Page::XPS::ImageMode::FitToBox));
33
34 // Save resultant XPS document
35 doc->Save(dataDir + u"UseImageUtilsXPS_out.xps");
36 }
37 catch(...)
38 {
39 __dispose_guard_0.SetCurrentException(std::current_exception());
40 }
41 }
42 // ExEnd:UsingImageUtils
Опять же, мы начинаем с нового документа XPS и настраиваем размер первой страницы. Стоит отметить, что по умолчанию ваше изображение, используемое в качестве кисти, будет располагаться в виде мозаики по прямоугольной области так же, как если бы оно использовалось в режиме XpsTileMode.Tile. Однако в первой части примера мы показываем, как предотвратить такое размещение.
Итак, сначала мы хотим, чтобы изображение отображалось в точке (10, 10) и соответствовало ширине прямоугольного блока шириной 200 единиц и высотой 200 единиц. Чтобы увидеть результат более наглядно, мы сначала рисуем сам блок. Затем мы создаем изображение (обратите внимание, что на самом деле это заполненный контур). Наконец, после получения заливки пути и приведения ее к
XpsImageBrush, мы устанавливаем свойство TileMode
на XpsTileMode.None
.
Справа мы размещаем то же изображение и подгоняем его под высоту блока изображения. Обратите внимание на мозаичность.
Наконец, мы снова размещаем то же изображение справа и подгоняем его под высоту и ширину блока изображения, что искажает изображение.
А вот результат в сохраненном файле XPS: