Vectorafbeeldingen tekenen op een PDF-pagina
Vectorafbeeldingen tekenen op een PDF-pagina
Aspose.PDF FOSS voor C++ bevat een kleine vector-graphics API voor het direct tekenen van vormen op een PDF-pagina terwijl een document wordt opgebouwd. Het toegangspunt is Graph, een container op een pagina die een verzameling Shape-objecten bevat; drie concrete vormen — Circle, Ellipse en Line — erven van Shape en geven elk hun geometrie op een andere manier weer. Per-vorm stroke- en fill-styling komt van GraphInfo, en de Graph-container zelf draagt een BorderInfo voor omlijsten. Dit staat los van paginarasterisatie (BmpDevice, JpegDevice, TiffDevice), die bestaande paginainhoud omzet naar raster-image-formaten in plaats van nieuwe geometrie te tekenen.
De grafiekcontainer en vormen toevoegen aan een pagina
Graph positioneert en dimensioneert zichzelf op de pagina via Left(), Top(), Width() en Height(), en de IsChangePosition()-vlag bepaalt of die positie kan verschuiven ten opzichte van andere paginainhoud. De vormen die het tekent bevinden zich in de vector die wordt geretourneerd door Shapes() — std::vector<std::unique_ptr<Shape>> — die wordt gevuld door een vorm te construeren, configureren en naar die vector te verplaatsen. Zodra de vorm gebouwd is, wordt de Graph zelf op de pagina geplaatst via Page.Paragraphs().Add(), dezelfde collectie die wordt gebruikt voor andere paginaniveau-inhoud.
#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");Cirkels en ellipsen tekenen
Circle en Ellipse geven elk geometrie weer als eenvoudige numerieke eigenschappen in plaats van een gedeeld punt- of rechthoektype. Circle is een middelpunt en straal — PosX(), PosY(), Radius() — terwijl Ellipse een omhullende doos is — Left(), Bottom(), Width(), Height(). Beide erven CheckBounds(containerWidth, containerHeight) van Shape, die aangeeft of de huidige geometrie van de vorm binnen een container van de opgegeven grootte past zonder de vorm zelf aan te passen.
#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);Lijnen tekenen met PositionArray
Line slaat zijn geometrie op op een andere manier dan Circle en Ellipse: PositionArray() geeft een plat std::vector<float> terug dat een x-y-paar bevat voor elk punt dat de lijn passeert, in plaats van een vaste set benoemde eigenschappen. Twee punten (vier waarden) tekenen een rechte segment; extra paren tekenen een meersegmentenpad door die punten in volgorde. Net als de andere vormen, Line overschrijft CheckBounds(containerWidth, containerHeight) van 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);Vormen stylen met GraphInfo en BorderInfo
Elke vorm leest en schrijft zijn lijn- en vulopmaak via Shape.GraphInfo() / GraphInfo(value). GraphInfo heeft standaard een LineWidth() van 1.0f met een lege DashArray(), en biedt ook Color(), FillColor(), DashArray()/DashPhase() voor gestippelde lijnen, IsDoubled() voor een dubbele lijn, en SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY() en RotationAngle() voor het transformeren van de lijn. Graph zelf bevat een BorderInfo, ingesteld via Border(), die één GraphInfo per rand groepeert — Left(), Right(), Top(), Bottom() — plus een RoundedBorderRadius(), en kan worden opgebouwd door aan te geven welke randen te stijlen met een BorderSide-vlag (BorderSide::Left | BorderSide::Right, of BorderSide::All voor elke rand).
#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);Tips en best practices
- Roep
CheckBoundsaan op de eigenWidth()/Height()van de eigenaar-Graph, niet op de volledige mediabox van de pagina — de check valideert de geometrie van een vorm ten opzichte van de opgegeven container-grootte, en kijkt niet automatisch naar de pagina. - Voeg vormen toe aan
Shapes()voordat je deGraphaanPage.Paragraphs()toevoegt — het construeren van eenCircle,EllipseofLineheeft geen zichtbaar effect totdat deze zowel is toegevoegd aan zijn eigenaar-Graphals dat dieGraphaan een pagina wordt toegevoegd. - Groeperen gerelateerde vormen onder één
Graphi.p.v. éénGraphper vorm;Left()/Top()/Width()/Height()positioneren de hele container één keer, en elke vorm inShapes()wordt relatief tot die getekend. - Stel
Shape.GraphInfo()expliciet in voor vormen die een zichtbare vulling of een niet-standaard lijn nodig hebben — de standaardGraphInfoheeft een1.0flijnbreedte, geen vulling en een legeDashArray(). - Bouw
Line.PositionArray()alsx0, y0, x1, y1, …paren in de volgorde waarin het pad getekend moet worden — een vector met oneven lengte beschrijft een onvolledig punt.
Veelvoorkomende problemen
| Probleem | Oorzaak | Oplossing |
|---|---|---|
Een Circle, Ellipse of Line verschijnt nooit op de opgeslagen pagina | De vorm werd geconstrueerd maar nooit toegevoegd aan de Graph’s Shapes(), of de Graph werd nooit aan de pagina toegevoegd | Plaats de vorm op graph->Shapes() en roep page.Paragraphs().Add(graph) aan |
| Vorm wordt getekend met een standaard dunne zwarte lijn | Shape.GraphInfo() is nooit ingesteld | Roep shape->GraphInfo(customGraphInfo) aan voordat je de vorm toevoegt aan Shapes() |
Line ontbreekt of lijkt op een enkel punt | PositionArray() heeft minder dan twee (x, y)-paren, of een oneven aantal waarden | Voorzie ten minste vier waarden als x0, y0, x1, y1 |
| Alleen enkele randen van de containergrens zijn gestileerd | BorderInfo is geconstrueerd met een BorderSide-masker dat enkele randen uitsluit | Gebruik BorderSide::All, of combineer alle benodigde BorderSide-vlaggen met OR |
CheckBounds retourneert onverwacht false | Afmetingen die aan CheckBounds worden doorgegeven komen niet overeen met de container waarin de vorm daadwerkelijk wordt getekend | Geef de huidige Width()/Height() van het eigenaar-Graph door |
FAQ
Wat is het verschil tussen Circle en AnnotationType::Circle?
Circle (deze gids) is een tekenvorm die rechtstreeks in de paginainhoud tekent via een Graph. AnnotationType::Circle en CircleAnnotation behoren tot een aparte annotaties API en vertegenwoordigen een cirkelvormige markup-annotatie — de twee zijn niet verwant ondanks de gedeelde naam.
Kan een enkele Graph meer dan één vorm bevatten?
Ja. Graph.Shapes() retourneert de volledige std::vector<std::unique_ptr<Shape>> voor die container, en elke combinatie van Circle, Ellipse en Line instanties kan eraan worden toegevoegd voordat de Graph aan de pagina wordt toegevoegd.
Delen Circle en Ellipse een geometrisch type?
Nee. Circle is een middelpunt en straal (PosX, PosY, Radius); Ellipse is een begrenzingsvak (Left, Bottom, Width, Height). Beide zijn afgeleid van Shape, maar geen van beide deelt een gemeenschappelijk punt of rechthoektype met de ander.
Is het tekenen van vormen met Graph hetzelfde als een pagina renderen naar een afbeelding?
Nee. Graph, Shape, Circle, Ellipse en Line bouwen nieuwe vector geometrie in de inhoud van een pagina tijdens het genereren van het document. Het omzetten van een bestaande pagina naar een rasterafbeelding is een aparte functionaliteit, afgehandeld door BmpDevice, JpegDevice en TiffDevice.
Wat doet GraphInfo.IsDoubled()?
Het markeert de lijn als een dubbele lijn in plaats van een andere lijneigenschap te wijzigen. Het is een booleaanse vlag die wordt gelezen en ingesteld via IsDoubled() / IsDoubled(value) naast de andere GraphInfo lijneigenschappen.
API Reference Samenvatting
| Klasse/Methode | Beschrijving |
|---|---|
Graph | Vormcontainer geplaatst op een pagina; positioneert zichzelf met Left(), Top(), Width(), Height() |
Graph.Shapes() | Retourneert de std::vector<std::unique_ptr<Shape>> die door deze container wordt getekend |
Graph.GraphInfo() / GraphInfo(value) | Haalt op / stelt de eigen lijn- en vulstijl van de container in |
Graph.Border() / Border(value) | Haalt op / stelt de BorderInfo die de container omkadert in |
Shape | Abstracte basis voor Circle, Ellipse en Line; maakt GraphInfo() en CheckBounds() beschikbaar |
Shape.CheckBounds(w, h) | Rapporteert of de geometrie van de vorm binnen een container van de opgegeven breedte/hoogte past |
Circle | Cirkelvorm: PosX(), PosY(), Radius() |
Ellipse | Ellipsvorm: omsluitende rechthoek via Left(), Bottom(), Width(), Height() |
Line | Lijn-/padvorm: PositionArray(), een vlakke std::vector<float> van x- en y-coördinaten |
GraphInfo | Lijn-/vullingsstijl: LineWidth(), Color(), FillColor(), DashArray(), DashPhase(), IsDoubled(), RotationAngle(), SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY() |
BorderInfo | Rand per containerkant: Left(), Right(), Top(), Bottom() (elk een GraphInfo), plus RoundedBorderRadius() |
BorderSide | Enum die randen selecteert bij het construeren van een BorderInfo: None, Left, Top, Right, Bottom, All, Box |