Kreslení vektorové grafiky na stránce PDF
Kreslení vektorové grafiky na stránce PDF
Aspose.PDF FOSS pro C++ zahrnuje malý vektorový grafický API pro kreslení tvarů přímo na stránku PDF během vytváření dokumentu. Vstupním bodem je Graph, kontejner umístěný na stránce, který drží kolekci objektů Shape; tři konkrétní tvary — Circle, Ellipse a Line — odvozují od Shape a každý vyjadřuje svou geometrii odlišně. Stylování obrysů a výplní pro jednotlivé tvary pochází z GraphInfo a samotný kontejner Graph nese BorderInfo pro rámování. To nesouvisí s rasterizací stránky (BmpDevice, JpegDevice, TiffDevice), která převádí existující obsah stránky do rastrových formátů obrázků místo kreslení nové geometrie.
Kontejner grafu a přidávání tvarů na stránku
Graph určuje svou polohu a velikost na stránce pomocí Left(), Top(), Width() a Height(), a jeho příznak IsChangePosition() řídí, zda se tato pozice může posunout vzhledem k ostatnímu obsahu stránky. Tvary, které kreslí, žijí ve vektoru vráceném Shapes() — std::vector<std::unique_ptr<Shape>> — naplněném vytvořením tvaru, jeho konfigurací a přesunutím na tento vektor. Po vytvoření je samotný Graph umístěn na stránku pomocí Page.Paragraphs().Add(), stejné kolekce používané pro ostatní obsah na úrovni stránky.
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/drawing/graph.hpp>
#include <aspose/pdf/drawing/circle.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Drawing;
Document doc;
Page page = doc.Pages().Add();
auto graph = std::make_shared<Graph>();
graph->Left(36.0);
graph->Top(36.0);
graph->Width(500.0);
graph->Height(300.0);
auto marker = std::make_unique<Circle>();
marker->PosX(60.0);
marker->PosY(60.0);
marker->Radius(30.0);
graph->Shapes().push_back(std::move(marker));
page.Paragraphs().Add(graph);
doc.Save("shapes.pdf");Kreslení kruhů a elips
Circle a Ellipse vyjadřují geometrii jako prosté číselné vlastnosti namísto sdíleného typu bodu nebo obdélníku. Circle je středový bod a poloměr — PosX(), PosY(), Radius() — zatímco Ellipse je ohraničující rámeček — Left(), Bottom(), Width(), Height(). Oba dědí CheckBounds(containerWidth, containerHeight) z Shape, který uvádí, zda aktuální geometrie tvaru zapadá do kontejneru dané velikosti, aniž by měnil samotný tvar.
#include <aspose/pdf/drawing/circle.hpp>
#include <aspose/pdf/drawing/ellipse.hpp>
using namespace Aspose::Pdf::Drawing;
Circle circle;
circle.PosX(120.0);
circle.PosY(120.0);
circle.Radius(60.0);
bool circleFits = circle.CheckBounds(500.0, 300.0);
Ellipse ellipse;
ellipse.Left(220.0);
ellipse.Bottom(20.0);
ellipse.Width(250.0);
ellipse.Height(100.0);
bool ellipseFits = ellipse.CheckBounds(500.0, 300.0);Kreslení čar s PositionArray
Line ukládá svou geometrii odlišně od Circle a Ellipse: PositionArray() vrací plochý std::vector<float> obsahující pár x, y pro každý bod, kterým čára prochází, místo pevně dané sady pojmenovaných vlastností. Dva body (čtyři hodnoty) vykreslí přímý úsek; další páry vykreslí víceúsečkovou cestu skrz tyto body v pořadí. Stejně jako ostatní tvary, Line přepisuje CheckBounds(containerWidth, containerHeight) z Shape.
#include <aspose/pdf/drawing/line.hpp>
using namespace Aspose::Pdf::Drawing;
Line path;
path.PositionArray({0.0f, 0.0f, 250.0f, 0.0f, 125.0f, 200.0f});
bool pathFits = path.CheckBounds(500.0, 300.0);Stylování tvarů pomocí GraphInfo a BorderInfo
Každý tvar čte a zapisuje své nastavení tahu a výplně přes Shape.GraphInfo() / GraphInfo(value). GraphInfo ve výchozím nastavení používá LineWidth() 1.0f s prázdným DashArray() a také poskytuje Color(), FillColor(), DashArray()/DashPhase() pro čárkované tahy, IsDoubled() pro dvojitý tah a SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY() a RotationAngle() pro transformaci tahu. Graph samotný nese BorderInfo, nastavený přes Border(), který seskupuje jeden GraphInfo na každou hranu — Left(), Right(), Top(), Bottom() — plus RoundedBorderRadius(), a lze jej vytvořit pojmenováním, které hrany stylovat, pomocí příznaku BorderSide (BorderSide::Left | BorderSide::Right nebo BorderSide::All pro každou hranu).
#include <aspose/pdf/graph_info.hpp>
#include <aspose/pdf/border_info.hpp>
#include <aspose/pdf/border_side.hpp>
#include <aspose/pdf/color.hpp>
using namespace Aspose::Pdf;
GraphInfo stroke;
stroke.LineWidth(2.5f);
stroke.Color(Color::FromRgb(1.0, 0.0, 0.0));
stroke.DashArray({3, 2});
stroke.DashPhase(1);
stroke.IsDoubled(true);
// Style only the left and right edges of the container border.
BorderInfo border{BorderSide::Left | BorderSide::Right, 3.0f};
border.RoundedBorderRadius(4.0);
graph->GraphInfo(stroke);
graph->Border(border);Tipy a osvědčené postupy
- Zavolejte
CheckBoundsproti vlastnímWidth()/Height()vlastněnéhoGraph, ne proti celé mediální krabici stránky — kontrola ověřuje geometrii tvaru vůči jakékoli velikosti kontejneru, kterou předáte, a neprohlíží stránku automaticky. - Přidejte tvary do
Shapes()před tím, než přidáteGraphdoPage.Paragraphs()— vytvořeníCircle,EllipseneboLinenemá žádný viditelný efekt, dokud není připojeno k vlastnímuGrapha tentoGraphnení přidán na stránku. - Seskupte související tvary pod jediným
Graphmísto jednohoGraphna tvar;Left()/Top()/Width()/Height()umístí celý kontejner jednou a každý tvar vShapes()je vykreslen relativně k němu. - Nastavte
Shape.GraphInfo()explicitně pro tvary, které potřebují viditelnou výplň nebo netradiční tah — výchozíGraphInfomá1.0fšířku čáry, žádnou výplň a prázdnýDashArray(). - Vytvořte
Line.PositionArray()jakox0, y0, x1, y1, …páry v pořadí, v jakém má být cesta vykreslena — vektor liché délky popisuje neúplný bod.
Časté problémy
| Problém | Příčina | Oprava |
|---|---|---|
A Circle, Ellipse nebo Line se nikdy neobjeví na uložené stránce | Tvar byl vytvořen, ale nikdy nebyl připojen k Graph’s Shapes(), nebo Graph nebyl nikdy přidán na stránku | Vložte tvar na graph->Shapes() a zavolejte page.Paragraphs().Add(graph) |
| Tvar se vykresluje s výchozím tenkým černým obrysem | Shape.GraphInfo() nebyl nikdy nastaven | Zavolejte shape->GraphInfo(customGraphInfo) před přidáním tvaru do Shapes() |
Line chybí nebo vypadá jako jediný bod | PositionArray() má méně než dva páry (x, y) nebo lichý počet hodnot | Zadejte alespoň čtyři hodnoty jako x0, y0, x1, y1 |
| Pouze některé hrany ohraničení kontejneru jsou stylizovány | BorderInfo byl vytvořen s maskou BorderSide, která vylučuje některé hrany | Použijte BorderSide::All nebo pomocí OR spojte všechny potřebné příznaky BorderSide |
CheckBounds neočekávaně vrací false | Rozměry předané do CheckBounds neodpovídají kontejneru, ve kterém je tvar skutečně vykreslen | Předat aktuální Width()/Height() vlastníka Graph |
FAQ
Jaký je rozdíl mezi Circle a AnnotationType::Circle?
Circle (tento návod) je kreslicí tvar, který kreslí přímo do obsahu stránky prostřednictvím Graph. AnnotationType::Circle a CircleAnnotation patří k samostatnému anotacnímu API a představují značkovou anotaci ve tvaru kruhu — tyto dva nejsou navzájem spojeny navzdory sdílenému názvu.
Může jeden Graph obsahovat více než jeden tvar?
Ano. Graph.Shapes() vrací celý std::vector<std::unique_ptr<Shape>> pro tento kontejner a jakákoli kombinace instancí Circle, Ellipse a Line může být k němu připojena předtím, než je Graph přidáno na stránku.
Mají Circle a Ellipse společný geometrický typ?
Ne. Circle je středový bod a poloměr (PosX, PosY, Radius); Ellipse je ohraničující rámeček (Left, Bottom, Width, Height). Oba jsou odvozeny od Shape, ale žádný z nich nesdílí společný bod ani typ obdélníku s druhým.
Je kreslení tvarů pomocí Graph stejné jako vykreslení stránky do obrázku?
Ne. Graph, Shape, Circle, Ellipse a Line vytvářejí novou vektorovou geometrii v obsahu stránky během generování dokumentu. Převod existující stránky na rastrový obrázek je samostatná funkce, kterou zajišťují BmpDevice, JpegDevice a TiffDevice.
Co dělá GraphInfo.IsDoubled()?
Označuje stroke jako dvojitou čáru, místo aby měnil jakoukoli jinou vlastnost stroke. Jedná se o booleanový příznak, který se čte a nastavuje přes IsDoubled() / IsDoubled(value) spolu s ostatními vlastnostmi stroke GraphInfo.
API Reference Shrnutí
| Třída/metoda | Popis: |
|---|---|
Graph | Kontejner tvaru umístěný na stránce; umisťuje se pomocí Left(), Top(), Width(), Height() |
Graph.Shapes() | Vrací std::vector<std::unique_ptr<Shape>> vykreslený tímto kontejnerem |
Graph.GraphInfo() / GraphInfo(value) | Získává/nastavuje vlastní styl čáry a výplně kontejneru |
Graph.Border() / Border(value) | Získává/nastavuje BorderInfo ohraničující kontejner |
Shape | Abstraktní základ pro Circle, Ellipse a Line; poskytuje GraphInfo() a CheckBounds() |
Shape.CheckBounds(w, h) | Hlásí, zda geometrie tvaru zapadá do kontejneru s danou šířkou/výškou |
Circle | Kruhový tvar: PosX(), PosY(), Radius() |
Ellipse | Elipsový tvar: ohraničující rámeček pomocí Left(), Bottom(), Width(), Height() |
Line | Tvar čáry/cesty: PositionArray(), plochý std::vector<float> x, y souřadnic |
GraphInfo | Styling tahu/výplně: LineWidth(), Color(), FillColor(), DashArray(), DashPhase(), IsDoubled(), RotationAngle(), SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY() |
BorderInfo | Okraj kontejneru na každé hraně: Left(), Right(), Top(), Bottom() (každý je GraphInfo), plus RoundedBorderRadius() |
BorderSide | Výčet výběru hran při vytváření BorderInfo: None, Left, Top, Right, Bottom, All, Box |