C++ में PDF ग्राफ़िक्स के साथ कैसे काम करें

C++ में PDF ग्राफ़िक्स के साथ कैसे काम करें

Aspose.PDF FOSS for C++ में एक छोटा वेक्टर-ग्राफिक्स API शामिल है जो PDF पेज पर सीधे फ्री-फ़ॉर्म आकार बनाने के लिए है — लाइब्रेरी के रास्टर-रेंडरिंग डिवाइस (BmpDevice, JpegDevice, TiffDevice) से अलग, जो मौजूदा पेज कंटेंट को इमेज में बदलते हैं। यह गाइड एक Graph कंटेनर बनाने, उसमें 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)

टूलचेन और हेडर्स के रिज़ॉल्व होने की जाँच एक न्यूनतम प्रोग्राम को कंपाइल करके करें:

#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 को अकेले बनाना तब तक कोई प्रभाव नहीं डालता जब तक उसे स्वामित्व वाले Graph के Shapes() द्वारा लौटाए गए वेक्टर में जोड़ नहीं दिया जाता, और वह Graph Page.Paragraphs().Add() के माध्यम से पृष्ठ में जोड़ी जाती है। इन तीनों चरणों — निर्माण, जोड़ना, Graph को पृष्ठ में जोड़ना — सभी आवश्यक हैं।

आकार गलत स्थिति में रेंडर होते हैं

Graph.Left() और Graph.Top() पृष्ठ पर कंटेनर की स्थिति निर्धारित करते हैं; आकार की विशेषताएँ (Circle.PosX()/PosY(), Ellipse.Left()/Bottom(), Line.PositionArray() निर्देशांक) उस कंटेनर के भीतर ज्यामिति का वर्णन करती हैं। जब आउटपुट ऑफसेट दिखे तो कंटेनर की प्लेसमेंट और आकार के स्वयं के निर्देशांक दोनों की जाँच करें।

CheckBounds returns false unexpectedly

CheckBounds(containerWidth, containerHeight) आकार की अपनी ज्यामिति को पास की गई आयामों के खिलाफ जांचता है — आमतौर पर स्वामित्व वाले Graph के Width()/Height(), न कि पृष्ठ के पूर्ण मीडिया बॉक्स के। गलत आयाम पास करने से एक झूठा नकारात्मक परिणाम मिलता है, भले ही आकार वास्तव में Graph के भीतर फिट हो।

A Line नहीं दिखता, या एक बिंदु के रूप में दिखता है

PositionArray() को कम से कम दो (x, y) जोड़े — चार float मान — चाहिए एक दृश्य खंड का वर्णन करने के लिए। एक छोटा वेक्टर लाइन नहीं बनाता।

Confusing Circle with AnnotationType::Circle or CircleAnnotation

लाइब्रेरी में एक अलग PDF एनोटेशन API भी है, जहाँ 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.Shapes() उस Graph के भीतर रखे गए Shape वस्तुओं का पूरा संग्रह लौटाता है — वृत्त, दीर्घवृत्त, और रेखाएँ सभी को एक ही कंटेनर में जोड़ा जा सकता है।

क्या यह पृष्ठ को छवि में रेंडर करने के समान है?

नहीं। BmpDevice, JpegDevice, और TiffDevice मौजूदा पृष्ठ सामग्री को छवि स्वरूपों में रास्टराइज़ करते हैं। Graph, Shape, Circle, Ellipse, और Line दस्तावेज़ बनते या संपादित होते समय PDF सामग्री में सीधे नया वेक्टर ज्यामिति बनाते हैं।

यह भी देखें

 हिन्दी