Πώς να εργαστείτε με γραφικά PDF σε C++

Πώς να εργαστείτε με γραφικά PDF σε C++

Aspose.PDF FOSS for C++ περιλαμβάνει ένα μικρό API διανυσματικών γραφικών για τη σχεδίαση ελεύθερων σχημάτων απευθείας σε μια σελίδα PDF — ξεχωριστό από τις συσκευές raster-rendering της βιβλιοθήκης (BmpDevice, JpegDevice, TiffDevice), που μετατρέπουν το υπάρχον περιεχόμενο της σελίδας σε εικόνες. Αυτός ο οδηγός περιγράφει τη δημιουργία ενός Graph container, την προσθήκη Circle, Ellipse και Line σχημάτων σε αυτό, τη μορφοποίηση αυτών των σχημάτων με GraphInfo, και την τοποθέτηση του τελικού Graph σε μια σελίδα. Η βιβλιοθήκη προστίθεται σε ένα έργο μέσω CMake.

Οδηγός βήμα-βήμα

Βήμα 1: Εγκατάσταση του πακέτου

Προσθέστε τη βιβλιοθήκη ως υποκατάλογο CMake και συνδέστε την με τον στόχο aspose_pdf_foss:

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

Επαληθεύστε ότι το toolchain και οι κεφαλίδες επιλύονται με τη μεταγλώττιση ενός ελάχιστου προγράμματος:

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

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

Μια επιτυχής κατασκευή που εκτυπώνει pages: 0 επιβεβαιώνει ότι η βιβλιοθήκη έχει συνδεθεί σωστά.


Βήμα 2: Εισαγωγή των Απαιτούμενων Κλάσεων

Συμπεριλάβετε τις κεφαλίδες για το έγγραφο, το κοντέινερ σχήματος, τα τρία συγκεκριμένα σχήματα και τους τύπους στυλ τους:

#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 και Line βρίσκονται στο χώρο ονομάτων Aspose::Pdf::Drawing; GraphInfo, BorderInfo και Color βρίσκονται απευθείας κάτω από το Aspose::Pdf.


Βήμα 3: Δημιουργία Γραφήματος και Προσθήκη του σε μια Σελίδα

Graph είναι ένα κοντέινερ που τοποθετείται στη σελίδα μέσω Left(), Top(), Width() και Height(), και κρατά τα σχήματα που σχεδιάζονται μέσα του μέσω Shapes(). Μόλις διαμορφωθεί, τοποθετείται στη σελίδα μέσω Page.Paragraphs().Add(), η ίδια συλλογή που χρησιμοποιείται για άλλο περιεχόμενο της σελίδας:

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: Σχεδίαση Κύκλου και Έλλειψης

Circle περιγράφει τη γεωμετρία του με PosX(), PosY() και Radius(). Ellipse χρησιμοποιεί ένα πλαίσιο περιθώριο αντί αυτού — Left(), Bottom(), Width() και Height(). Και τα δύο προστίθενται στο Graph προσθέτοντάς τα, ως δείκτες Shape, στο διάνυσμα που επιστρέφεται από το 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));

Και τα δύο σχήματα κληρονομούν το CheckBounds(containerWidth, containerHeight) από το Shape, το οποίο αναφέρει αν η τρέχουσα γεωμετρία του σχήματος χωράει μέσα σε ένα κοντέινερ του δοθέντος μεγέθους:

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

Βήμα 5: Σχεδίαση γραμμής

Line αποθηκεύει τη γεωμετρία του διαφορετικά: το PositionArray() περιέχει μια επίπεδη std::vector<float> συντεταγμένων — ένα ζεύγος x, y ανά σημείο — αντί για ονομαστικές ιδιότητες. Ένα τμήμα με δύο σημεία χρειάζεται τέσσερις τιμές: x έναρξης, y έναρξης, x λήξης, 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: Στυλιζάτε τα σχήματα με GraphInfo και το περίγραμμα του περιέκτη

Κάθε γραμμή και γέμισμα σχήματος προέρχονται από ένα GraphInfo, που διαβάζεται και ορίζεται μέσω Shape.GraphInfo() / GraphInfo(value). Εκθέτει το πλάτος της γραμμής (LineWidth(), προεπιλογή 1.0f), το χρώμα γραμμής και γέμισμα (Color(), FillColor()), και ένα μοτίβο παύλων (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 περιέχει ένα BorderInfo, που ορίζεται μέσω Border(), το οποίο ομαδοποιεί ένα GraphInfo ανά άκρη (Left(), Right(), Top(), Bottom()) συν ένα RoundedBorderRadius() για το ίδιο το πλαίσιο του περιέκτη:

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

Βήμα 7: Αποθήκευση του εγγράφου

doc.Save("graphics.pdf");

Κοινά προβλήματα και διορθώσεις

Ένα σχήμα που δημιούργησα δεν εμφανίζεται ποτέ στη σελίδα

Η δημιουργία ενός Circle, Ellipse ή Line από μόνη της δεν έχει κανένα αποτέλεσμα μέχρι να προσαρμοστεί στο διάνυσμα που επιστρέφει το Shapes() του ιδιοκτήτη Graph, και αυτό το Graph προσαρμοστεί σε μια σελίδα μέσω Page.Paragraphs().Add(). Απαιτούνται και τα τρία βήματα — δημιουργία, προσθήκη, προσθήκη του Graph στη σελίδα —.

Τα σχήματα αποδίδονται σε λανθασμένη θέση

Graph.Left() και Graph.Top() τοποθετούν το κοντέινερ στη σελίδα· οι ιδιότητες του σχήματος (Circle.PosX()/PosY(), Ellipse.Left()/Bottom(), συντεταγμένες Line.PositionArray()) περιγράφουν τη γεωμετρία μέσα σε αυτό το κοντέινερ. Ελέγξτε τόσο τη θέση του κοντέινερ όσο και τις δικές του συντεταγμένες όταν η έξοδος φαίνεται μετατοπισμένη.

CheckBounds returns false unexpectedly

CheckBounds(containerWidth, containerHeight) ελέγχει τη γεωμετρία του σχήματος σε σχέση με τις διαστάσεις που περάστηκαν — συνήθως τις Width()/Height() του ιδιοκτήτη Graph, όχι το πλήρες media box της σελίδας. Η μετάδοση λανθασμένων διαστάσεων δημιουργεί ψευδές αρνητικό αποτέλεσμα ακόμα και όταν το σχήμα θα χωρούσε στην Graph.

Α Line δεν εμφανίζεται, ή εμφανίζεται ως ένα μόνο σημείο

PositionArray() χρειάζεται τουλάχιστον δύο ζεύγη (x, y) — τέσσερις τιμές float — για να περιγράψει ένα ορατό τμήμα. Ένα πιο σύντομο διάνυσμα δεν σχηματίζει γραμμή.

Confusing Circle with AnnotationType::Circle or CircleAnnotation

Η βιβλιοθήκη διαθέτει επίσης ξεχωριστό API σημειώσεων PDF, όπου τα AnnotationType::Circle και CircleAnnotation αντιπροσωπεύουν σημειώσεις σχήματος κύκλου. Η κλάση Circle που καλύπτεται σε αυτόν τον οδηγό δεν σχετίζεται — βρίσκεται στο Aspose::Pdf::Drawing και σχεδιάζει απευθείας στο περιεχόμενο της σελίδας αντί να προσθέτει αντικείμενο σημείωσης.

Συχνές ερωτήσεις

Ποια είναι η διαφορά μεταξύ GraphInfo και BorderInfo;

GraphInfo μορφοποιεί μια μονή γραμμή — πλάτος γραμμής, χρώμα, χρώμα γεμίσματος και μοτίβο παύλων — και χρησιμοποιείται τόσο σε μεμονωμένα σχήματα (μέσω Shape.GraphInfo()) όσο και ανά άκρο μέσα σε ένα BorderInfo. BorderInfo ομαδοποιεί τέσσερις τιμές GraphInfo (Left(), Right(), Top(), Bottom()) συν ένα RoundedBorderRadius() για να περιγράψει το δικό του πλαίσιο περιγράμματος ενός Graph δοχείου.

Μπορώ να γεμίσω ένα σχήμα με ένα συμπαγές χρώμα;

Ναι. GraphInfo.FillColor() ορίζει το χρώμα γεμίσματος που χρησιμοποιείται όταν το σχήμα σχεδιάζεται μέσω του ιδιοκτήτη του Graph.

Το Circle αποθηκεύει ένα πλαίσιο περιβάλλουσας όπως κάνει το Ellipse;

Όχι. Circle εκθέτει PosX(), PosY() και Radius(); Ellipse εκθέτει Left(), Bottom(), Width() και Height(). Δεν μοιράζονται κοινή αναπαράσταση γεωμετρίας πέρα από τη αφηρημένη βάση Shape και το στυλ GraphInfo.

Μπορεί ένα Graph να περιέχει περισσότερα από ένα σχήμα;

Ναι. Graph.Shapes() επιστρέφει τη πλήρη συλλογή των αντικειμένων Shape που τοποθετούνται μέσα σε αυτό το Graph — κύκλοι, έλλειπτες και γραμμές μπορούν όλα να προσαρτηθούν στον ίδιο δοχείο.

Αυτό είναι το ίδιο με την απόδοση μιας σελίδας σε εικόνα;

Όχι. BmpDevice, JpegDevice και TiffDevice rasterize το υπάρχον περιεχόμενο της σελίδας σε μορφές εικόνας. Graph, Shape, Circle, Ellipse και Line δημιουργούν νέα διανυσματική γεωμετρία απευθείας στο περιεχόμενο PDF ενώ ένα έγγραφο δημιουργείται ή επεξεργάζεται.

Δείτε επίσης

 Ελληνικά