Hogyan dolgozzunk PDF grafikákkal C++-ban

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.

Lásd még:

 Magyar