C++ में PDF एनोटेशन के साथ कैसे काम करें
FOSS for C++ प्रत्येक PDF एनोटेशन को सामान्य Annotation बेस क्लास की सबक्लास के रूप में दर्शाता है, और Page::Annotations() द्वारा लौटाए गए AnnotationCollection के माध्यम से पेज पर एनोटेशन को उजागर करता है। यह गाइड TextAnnotation के साथ पेज में एक साधारण टेक्स्ट-नोट एनोटेशन और एक स्टाइल्ड एनोटेशन जोड़ता है, दस्तावेज़ को सहेजता है, फिर उसे पुनः खोलकर एनोटेशन को पुनः पढ़ता है और एक को हटाता है। लाइब्रेरी को एक CMake प्रोजेक्ट में सबडायरेक्टरी निर्भरता के रूप में एकीकृत किया गया है — कोई पैकेज-रजिस्ट्री इंस्टॉल चरण नहीं है।
स्टेप-बाय-स्टेप गाइड
स्टेप 1: पैकेज स्थापित करें
लाइब्रेरी को CMake सबडायरेक्टरी के रूप में जोड़ें और स्थैतिक लाइब्रेरी टार्गेट को लिंक करें:
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/page_collection.hpp>
#include <aspose/pdf/rectangle.hpp>
#include <aspose/pdf/color.hpp>
#include <aspose/pdf/annotations/annotation.hpp>
#include <aspose/pdf/annotations/annotation_collection.hpp>
#include <aspose/pdf/annotations/annotation_type.hpp>
#include <aspose/pdf/annotations/annotation_flags.hpp>
#include <aspose/pdf/annotations/border.hpp>
#include <aspose/pdf/annotations/border_style.hpp>
#include <aspose/pdf/annotations/text_annotation.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Annotations;चरण 3: एक दस्तावेज़ बनाएं और एक पृष्ठ जोड़ें
एक नया दस्तावेज़ बनाएं और उसमें एक पृष्ठ जोड़ें। PageCollection::Add() नया जोड़ा गया Page लौटाता है:
Document doc;
Page page = doc.Pages().Add();चरण 4: पृष्ठ में एक टेक्स्ट एनोटेशन जोड़ें
TextAnnotation एक स्टिकी-नोट शैली टिप्पणी के रूप में प्रदर्शित होता है। इसे मालिक Document से बनाएं, उसकी स्थिति Rect() से सेट करें और उसका संदेश Contents() से, फिर इसे पृष्ठ के AnnotationCollection में जोड़ें:
TextAnnotation note{doc};
note.Rect(Rectangle(100.0, 700.0, 200.0, 720.0, false));
note.Contents("Reviewed and approved.");
page.Annotations().Add(note);चरण 5: दूसरे एनोटेशन को रंग, बॉर्डर और फ़्लैग्स के साथ स्टाइल करें
Annotation additionally Color(), Border(), और Flags() भी उजागर करता है। Flags() एक AnnotationFlags बिट फ़ील्ड लेता है — एक साथ एक से अधिक फ़्लैग सेट करने के लिए मानों को बिटवाइज़ OR से मिलाएँ:
TextAnnotation flagged{doc};
flagged.Rect(Rectangle(100.0, 600.0, 300.0, 650.0, false));
flagged.Contents("Needs follow-up");
flagged.Color(Color::FromRgb(220, 20, 20));
flagged.Flags(AnnotationFlags::Print | AnnotationFlags::ReadOnly);
flagged.Border().Width(2);
flagged.Border().Style(BorderStyle::Dashed);
page.Annotations().Add(flagged);चरण 6: दस्तावेज़ सहेजें
जब तक Save() नहीं चलता, कोई भी डेटा डिस्क पर नहीं लिखा जाता:
doc.Save("annotated.pdf");चरण 7: PDF को पुनः खोलें और उसकी एनोटेशन पढ़ें
सहेजी गई फ़ाइल को पुनः खोलें और उसकी पहली पृष्ठ की AnnotationCollection वापस पढ़ें। AnnotationCollection 0-आधारित है, और Count() बताता है कि पृष्ठ में कितनी एनोटेशन हैं:
Document reopened("annotated.pdf");
auto& annots = reopened.Pages()[1].Annotations();
std::cout << "Annotation count: " << annots.Count() << "\n";
for (int i = 0; i < annots.Count(); ++i) {
const auto& a = annots[i];
if (a.AnnotationType() == AnnotationType::Text) {
std::cout << "Text annotation: " << a.Contents() << "\n";
}
}चरण 8: एक एनोटेशन हटाएँ और पुनः सहेजें
AnnotationCollection::Delete(index) 0-आधारित स्थिति द्वारा एक एनोटेशन हटाता है। पहला एनोटेशन हटाएँ और परिणाम को नई फ़ाइल में सहेजें:
annots.Delete(0);
reopened.Save("annotated-cleaned.pdf");सामान्य समस्याएँ और समाधान
कॉल करने के बाद सहेजे गए PDF में कुछ भी नहीं बदलता Annotations().Add()
यहाँ आम तौर पर दो चीज़ें गलत हो जाती हैं। पहला, PageCollection 1-आधारित है (doc.Pages()[1] पहला पृष्ठ है) जबकि AnnotationCollection 0-आधारित है (annots[0] पहली एनोटेशन है) — दो इंडेक्सिंग स्कीमों को मिलाने से गलत ऑब्जेक्ट पर काम किया जाता है। दूसरा, सुनिश्चित करें कि Document::Save() वास्तव में एनोटेशन जोड़ने के बाद चलता है; तब तक कुछ भी डिस्क पर लिखा नहीं जाता।
AnnotationCollection इंडेक्सिंग या Delete(index) throws std::out_of_range
वैध इंडेक्स 0 से Count() - 1 तक होते हैं। नकारात्मक इंडेक्स या Count() से बराबर या बड़ा इंडेक्स पास करने पर नियोजित रूप से std::out_of_range फेंका जाता है। किसी भी लूप या लुकअप को सीमित करने के लिए पहले Count() को कॉल करें।
Remove() returns false जब मैं वही एनोटेशन पर इसे दूसरी बार कॉल करता हूँ
यह कोई त्रुटि नहीं है। Remove() यह रिपोर्ट करता है कि एनोटेशन bool के रूप में मिला और हटाया गया; उसी एनोटेशन पर फिर से कॉल करना जो पहले ही हट चुका है, कोई ऑपरेशन नहीं करता और false लौटाता है। यह मानने के बजाय कि Remove() हमेशा सफल होता है, रिटर्न वैल्यू जांचें।
नया सेट करना AnnotationFlags मान उन फ़्लैग्स को साफ़ कर देता है जो मैंने पहले सेट किए थे
Flags(value) पूरे फ्लैग सेट को बदल देता है — यह पिछले मान के साथ मिलाता नहीं है। एकल फ्लैग जोड़ने या साफ़ करने के लिए, पहले वर्तमान फ्लैग पढ़ें और उन्हें बिटवाइज़ ऑपरेटर्स के साथ मिलाएँ, उदाहरण के लिए फ्लैग जोड़ने के लिए a.Flags(a.Flags() | AnnotationFlags::Print), या एक फ्लैग साफ़ करने के लिए a.Flags(a.Flags() & ~AnnotationFlags::Print) जबकि बाकी को अपरिवर्तित रखा जाए।
अक्सर पूछे जाने वाले प्रश्न
Annotation, TextAnnotation और अन्य एनोटेशन उपप्रकारों के बीच क्या संबंध है?
Annotation सामान्य बेस क्लास है। TextAnnotation और अन्य ठोस एनोटेशन प्रकार प्रत्येक इसे एक PDF एनोटेशन उपप्रकार के लिए विशेषीकृत करते हैं, जबकि बेस क्लास के Rect(), Contents(), Color(), Flags() और Border() एक्सेसर साझा करते हैं।
क्या एनोटेशन पूरे दस्तावेज़ के लिए या केवल एक पृष्ठ के लिए स्कोप्ड होते हैं?
प्रत्येक पृष्ठ का अपना AnnotationCollection होता है, जो उस पृष्ठ की Annotations() मेथड द्वारा लौटाया जाता है। एनोटेशन हमेशा उस पृष्ठ पर स्कोप्ड होते हैं जहाँ उन्हें जोड़ा गया था, न कि पूरे दस्तावेज़ पर।
मैं पृष्ठ पर कितने एनोटेशन हैं, यह कैसे गिनूँ?
Page::Annotations() द्वारा लौटाए गए AnnotationCollection पर Count() को कॉल करें।
क्या कोई एनोटेशन एक ही समय में प्रिंटेबल और रीड-ओनली दोनों हो सकता है?
हां। AnnotationFlags एक बिट फ़ील्ड है, इसलिए मानों को बिटवाइज़ OR से मिलाएँ, उदाहरण के लिए AnnotationFlags::Print | AnnotationFlags::ReadOnly।
क्या AnnotationCollection से एक एनोटेशन हटाने से वह डिस्क पर PDF फ़ाइल से भी हट जाता है?
केवल Document::Save() चलने के बाद। Delete(), Remove() और Clear() केवल इन-मेमोरी कलेक्शन को संशोधित करते हैं — डिस्क पर PDF तब तक अपरिवर्तित रहता है जब तक दस्तावेज़ सहेजा नहीं जाता।