Hogyan dolgozzunk PDF grafikákkal C++-ban
Aspose.PDF FOSS for C++ tartalmaz egy kis vektoros grafikai API eszközt, amely lehetővé teszi szabad formájú alakzatok közvetlen rajzolását egy PDF oldalon — elkülönítve a könyvtár raster-megjelenítő eszközeitől (BmpDevice, JpegDevice, TiffDevice), amelyek a meglévő oldal tartalmat képekké konvertálják. Ez az útmutató végigvezet egy Graph konténer létrehozásán, Circle, Ellipse és Line alakzatok hozzáadásán, ezeknek az alakzatoknak a GraphInfo stílusozásán, és a kész Graph elhelyezésén egy oldalon. A könyvtárat a projektbe CMake-en keresztül adhatjuk hozzá.
Lépésről-lépésre útmutató
1. lépés: A csomag telepítése
Adja hozzá a könyvtárat CMake alkönyvtárként, és linkelje a aspose_pdf_foss célhoz:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Ellenőrizze, hogy az eszközkészlet és a fejlécfájlok feloldódnak-e egy minimális program lefordításával:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}Egy sikeres fordítás, amely kiírja a pages: 0 értéket, megerősíti, hogy a könyvtár helyesen van linkelve.
2. lépés: Szükséges osztályok importálása
Tegye bele a dokumentum, a formakonténer, a három konkrét forma és azok stílus típusainak fejléceit:
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/drawing/graph.hpp>
#include <aspose/pdf/drawing/circle.hpp>
#include <aspose/pdf/drawing/ellipse.hpp>
#include <aspose/pdf/drawing/line.hpp>
#include <aspose/pdf/graph_info.hpp>
#include <aspose/pdf/border_info.hpp>
#include <aspose/pdf/color.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Drawing;Graph, Shape, Circle, Ellipse és Line a Aspose::Pdf::Drawing névtérben találhatók; GraphInfo, BorderInfo és Color közvetlenül a Aspose::Pdf alatt helyezkednek el.
3. lépés: Grafikon létrehozása és hozzáadása egy oldalhoz
Graph egy tároló, amely a Left(), Top(), Width() és Height() segítségével helyezi el magát az oldalon, és a Shapes() segítségével tartja a benne rajzolt formákat. Miután konfigurálva van, a Page.Paragraphs().Add() segítségével kerül az oldalra, amely ugyanaz a gyűjtemény, amelyet más oldal tartalmakhoz használnak:
Document doc;
Page page = doc.Pages().Add();
auto graph = std::make_shared<Graph>();
graph->Left(50.0);
graph->Top(50.0);
graph->Width(400.0);
graph->Height(400.0);
page.Paragraphs().Add(graph);4. lépés: Kör és ellipszis rajzolása
Circle a geometriai leírását a PosX(), PosY() és Radius() használatával adja meg. Ellipse helyette egy határoló dobozt használ — Left(), Bottom(), Width() és Height(). Mindkettőt a Graph-hez adják hozzá, úgy, hogy Shape mutatóként a Shapes() által visszaadott vektorhoz fűzik:
auto circle = std::make_unique<Circle>();
circle->PosX(150.0);
circle->PosY(150.0);
circle->Radius(75.0);
graph->Shapes().push_back(std::move(circle));
auto ellipse = std::make_unique<Ellipse>();
ellipse->Left(20.0);
ellipse->Bottom(20.0);
ellipse->Width(120.0);
ellipse->Height(60.0);
graph->Shapes().push_back(std::move(ellipse));Mindkét forma a CheckBounds(containerWidth, containerHeight)-t örökli a Shape-től, amely jelentést ad arról, hogy a forma aktuális geometriája belefér-e a megadott méretű tárolóba:
bool circleFits = circle->CheckBounds(graph->Width(), graph->Height());5. lépés: Vonal rajzolása
Line a geometriáját másképp tárolja: PositionArray() egy lapos std::vector<float> koordinátákat tartalmaz — pontonként egy x, y pár — a névvel ellátott tulajdonságok helyett. Egy kétpontos szegmensnek négy értékre van szüksége: kezdő x, kezdő y, vég x, vég y.
auto line = std::make_unique<Line>();
line->PositionArray({0.0f, 0.0f, 400.0f, 400.0f});
graph->Shapes().push_back(std::move(line));6. lépés: Alakzatok stílusozása GraphInfo és a konténer szegélyével
Az egyes alakzatok vonalvastagsága és kitöltése egy GraphInfoből származik, amelyet a Shape.GraphInfo() / GraphInfo(value) segítségével olvasnak és állítanak be. A következőket teszi elérhetővé: vonalvastagság (LineWidth(), alapértelmezett 1.0f), vonal- és kitöltőszín (Color(), FillColor()), valamint egy szaggatott minta (DashArray(), DashPhase()):
GraphInfo stroke;
stroke.LineWidth(2.0f);
stroke.Color(Color::FromRgb(1.0, 0.0, 0.0));
stroke.FillColor(Color::FromRgb(1.0, 0.9, 0.9));A Graph konténer maga egy BorderInfo tartalmaz, amelyet a Border() segítségével állítanak be, és minden élhez egy GraphInfo csoportosít (Left(), Right(), Top(), Bottom()), plusz egy RoundedBorderRadius() a konténer saját keretéhez:
BorderInfo border{BorderSide::All, 1.5f, Color::Black()};
border.RoundedBorderRadius(6.0);
graph->Border(border);7. lépés: Dokumentum mentése
doc.Save("graphics.pdf");Gyakori problémák és megoldások
Az általam létrehozott alakzat soha nem jelenik meg az oldalon
Egy Circle, Ellipse vagy Line önmagában történő létrehozása nem jár hatással, amíg nem fűzzük hozzá a tulajdonos Graph által visszaadott vektorhoz a Shapes() segítségével, és az a Graph egy oldalhoz kerül a Page.Paragraphs().Add() útján. A három lépés – létrehozás, hozzáfűzés, a Graph oldalhoz adása – mind szükséges.
Az alakzatok rossz helyen jelennek meg
Graph.Left() és Graph.Top() helyezik el a konténert az oldalon; az alakzat tulajdonságai (Circle.PosX()/PosY(), Ellipse.Left()/Bottom(), Line.PositionArray() koordináták) a konténeren belüli geometriát írják le. Ellenőrizze mind a konténer elhelyezését, mind az alakzat saját koordinátáit, ha a kimenet eltoltnak tűnik.
CheckBounds returns false unexpectedly
CheckBounds(containerWidth, containerHeight) az alakzat saját geometriáját a megadott méretekkel hasonlítja össze – általában a tulajdonos Graph Width()/Height() értékeivel, nem pedig az oldal teljes media box-ával. A helytelen méretek átadása hamis negatív eredményt ad még akkor is, ha az alakzat valójában belefér a Graph belsejébe.
A Line nem jelenik meg, vagy egyetlen pontként jelenik meg
PositionArray() legalább két (x, y) párra – négy float értékre – van szüksége egy látható szegmens leírásához. Egy rövidebb vektor nem alkot vonalat.
Confusing Circle with AnnotationType::Circle or CircleAnnotation
A könyvtárnak van egy külön PDF-annotációs API is, ahol a AnnotationType::Circle és a CircleAnnotation kör alakú jelölő annotációkat jelentenek. Az ebben az útmutatóban tárgyalt Circle osztály nem kapcsolódik ehhez — Aspose::Pdf::Drawing-ban található, és közvetlenül az oldal tartalmába rajzol, ahelyett, hogy annotációs objektumot adna hozzá.
Gyakran Ismételt Kérdések
Mi a különbség a GraphInfo és a BorderInfo között?
GraphInfo egyetlen vonalat stílusoz — vonalvastagság, szín, kitöltő szín és szaggatott minta — és használható mind egyedi alakzatokon (a Shape.GraphInfo() segítségével), mind egy BorderInfo élénként. BorderInfo négy GraphInfo értéket (Left(), Right(), Top(), Bottom()) plusz egy RoundedBorderRadius() csoportba foglal, hogy leírja egy Graph tároló saját keretét.
Kitölthetek egy alakzatot egyszínű színnel?
Igen. A GraphInfo.FillColor() beállítja a kitöltő színt, amelyet az alakzat a saját Graph segítségével rajzoláskor használ.
A Circle tárol-e körülíró dobozt, ahogy az Ellipse?
Nem. Circle megjeleníti a(z) PosX(), PosY() és Radius() elemeket; Ellipse megjeleníti a(z) Left(), Bottom(), Width() és Height() elemeket. Nem osztanak közös geometriai ábrázolást az absztrakt Shape alapon és a GraphInfo stíluson kívül.
Egy Graph tartalmazhat több mint egy alakzatot?
Igen. Graph.Shapes() visszaadja a(z) Shape objektumok teljes gyűjteményét, amely a(z) Graph belsejébe van elhelyezve — körök, ellipszisek és vonalak is hozzáadhatók ugyanahhoz a konténerhez.
Ez ugyanaz, mint egy oldal képpé renderelése?
Nem. BmpDevice, JpegDevice és TiffDevice raszterizálják a meglévő oldal tartalmat képfájlformátumokra. Graph, Shape, Circle, Ellipse és Line új vektoros geometriát hoznak létre közvetlenül a PDF tartalomban, miközben a dokumentum épül vagy szerkesztés alatt áll.