Jak pracovat s grafikou PDF v C++

Jak pracovat s grafikou PDF v C++

Aspose.PDF FOSS pro C++ zahrnuje malý vektorový API pro kreslení volně tvarovaných tvarů přímo na PDF stránce — oddělený od rasterových vykreslovacích zařízení knihovny (BmpDevice, JpegDevice, TiffDevice), která převádějí existující obsah stránky na obrázky. Tento průvodce popisuje vytvoření kontejneru Graph, přidání tvarů Circle, Ellipse a Line, stylování těchto tvarů pomocí GraphInfo a umístění hotového Graph na stránku. Knihovna je do projektu přidána pomocí CMake.

Průvodce krok za krokem

Krok 1: Nainstalujte balíček

Přidejte knihovnu jako podadresář CMake a propojte s cílem aspose_pdf_foss:

add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)

Ověřte, že toolchain a hlavičky jsou nalezeny, kompilací minimálního programu:

#include <aspose/pdf/document.hpp>
#include <iostream>

int main() {
    Aspose::Pdf::Document doc;
    std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}

Úspěšná kompilace, která vytiskne pages: 0, potvrzuje, že je knihovna správně propojena.


Krok 2: Naimportujte požadované třídy

Zahrňte hlavičky pro dokument, kontejner tvarů, tři konkrétní tvary a jejich typy stylování:

#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 a Line se nacházejí v jmenném prostoru Aspose::Pdf::Drawing; GraphInfo, BorderInfo a Color jsou přímo pod Aspose::Pdf.


Krok 3: Vytvořte graf a přidejte jej na stránku

Graph je kontejner, který se na stránce umisťuje pomocí Left(), Top(), Width() a Height() a obsahuje tvary nakreslené uvnitř pomocí Shapes(). Po nakonfigurování je umístěn na stránku pomocí Page.Paragraphs().Add(), stejné kolekce používané pro ostatní obsah stránky:

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);

Krok 4: Nakreslete kruh a elipsu

Circle popisuje svou geometrii pomocí PosX(), PosY() a Radius(). Ellipse používá místo toho ohraničující rámeček — Left(), Bottom(), Width() a Height(). Oba jsou přidány do Graph připojením jako ukazatele Shape do vektoru vráceného funkcí Shapes():

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));

Oba tvary dědí CheckBounds(containerWidth, containerHeight) z Shape, který hlásí, zda aktuální geometrie tvaru zapadá do kontejneru dané velikosti:

bool circleFits = circle->CheckBounds(graph->Width(), graph->Height());

Krok 5: Nakreslete čáru

Line ukládá svoji geometrii jinak: PositionArray() obsahuje plochý std::vector<float> souřadnic — dvojici x, y pro každý bod — místo pojmenovaných vlastností. Dvoubodový segment potřebuje čtyři hodnoty: startovní x, startovní y, koncové x, koncové y.

auto line = std::make_unique<Line>();
line->PositionArray({0.0f, 0.0f, 400.0f, 400.0f});
graph->Shapes().push_back(std::move(line));

Krok 6: Stylizujte tvary pomocí GraphInfo a okraje kontejneru

Obrys a výplň každého tvaru pocházejí z GraphInfo, čtou se a nastavují přes Shape.GraphInfo() / GraphInfo(value). Poskytuje šířku obrysu (LineWidth(), výchozí 1.0f), barvu obrysu a výplně (Color(), FillColor()) a vzor čáry (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));

Graph kontejner sám nese BorderInfo, nastavený přes Border(), který seskupuje jeden GraphInfo na každém okraji (Left(), Right(), Top(), Bottom()) plus RoundedBorderRadius() pro vlastní rám kontejneru:

BorderInfo border{BorderSide::All, 1.5f, Color::Black()};
border.RoundedBorderRadius(6.0);
graph->Border(border);

Krok 7: Uložte dokument

doc.Save("graphics.pdf");

Časté problémy a opravy

Tvar, který jsem vytvořil, se na stránce nikdy neobjeví

Vytvoření Circle, Ellipse nebo Line samostatně nemá žádný efekt, dokud není připojeno k vektoru vrácenému Shapes() vlastnického Graph, a tento Graph je přidán na stránku prostřednictvím Page.Paragraphs().Add(). Všechny tři kroky — vytvořit, připojit, přidat Graph na stránku — jsou vyžadovány.

Tvary se vykreslují na špatné pozici

Graph.Left() a Graph.Top() umisťují kontejner na stránku; vlastnosti tvaru (Circle.PosX()/PosY(), Ellipse.Left()/Bottom(), souřadnice Line.PositionArray()) popisují geometrie v rámci tohoto kontejneru. Zkontrolujte jak umístění kontejneru, tak i souřadnice samotného tvaru, pokud se výstup jeví posunutý.

CheckBounds returns false unexpectedly

CheckBounds(containerWidth, containerHeight) kontroluje geometrické údaje tvaru vůči předaným rozměrům — obvykle Width()/Height() vlastnického Graph, nikoli plnému mediálnímu rámečku stránky. Předání nesprávných rozměrů vede k falešnému negativu i když by tvar ve Graph skutečně zapadal.

A Line neobjevuje se, nebo se objeví jako jediný bod

PositionArray() potřebuje alespoň dva (x, y) páry — čtyři hodnoty float — k popisu viditelného úseku. Kratší vektor nevytvoří čáru.

Confusing Circle with AnnotationType::Circle or CircleAnnotation

Knihovna má také samostatný API pro PDF anotace, kde AnnotationType::Circle a CircleAnnotation představují kruhové značky. Třída Circle popsaná v tomto průvodci není související — nachází se v Aspose::Pdf::Drawing a kreslí přímo do obsahu stránky místo přidání objektu anotace.

Často kladené otázky

Jaký je rozdíl mezi GraphInfo a BorderInfo?

GraphInfo stylizuje jednotlivý tah — šířku čáry, barvu, barvu výplně a vzor čárkování — a používá se jak na jednotlivé tvary (prostřednictvím Shape.GraphInfo()), tak na každou hranu uvnitř BorderInfo. BorderInfo seskupuje čtyři hodnoty GraphInfo (Left(), Right(), Top(), Bottom()) plus RoundedBorderRadius(), aby popsal vlastní rámeček ohraničení kontejneru Graph.

Mohu vyplnit tvar plnou barvou?

Ano. GraphInfo.FillColor() nastavuje barvu výplně používanou, když je tvar vykreslen přes jeho vlastní Graph.

Ukládá Circle ohraničující rámeček jako Ellipse?

Ne. Circle vystavuje PosX(), PosY() a Radius(); Ellipse vystavuje Left(), Bottom(), Width() a Height(). Nemají společnou reprezentaci geometrie mimo abstraktní základ Shape a stylování GraphInfo.

Může jeden graf obsahovat více než jeden tvar?

Ano. Graph.Shapes() vrací kompletní kolekci objektů Shape umístěných v tomto Graph — kruhy, elipsy a čáry mohou být všechny přidány do stejného kontejneru.

Je to stejné jako renderování stránky do obrázku?

Ne. BmpDevice, JpegDevice a TiffDevice rasterizují existující obsah stránky do obrazových formátů. Graph, Shape, Circle, Ellipse a Line vytvářejí novou vektorovou geometriku přímo v obsahu PDF, zatímco je dokument vytvářen nebo upravován.

Viz také:

 Čeština