العمل مع تعليقات PDF
العمل مع تعليقات PDF
تمثّل تعليقات PDF في Aspose.PDF FOSS للـ C++ الفئة الأساسية Annotation وأنواعها الفرعية المطبقة (TextAnnotation، LinkAnnotation، HighlightAnnotation، FreeTextAnnotation، CircleAnnotation، WatermarkAnnotation، WidgetAnnotation، وغيرها). كل صفحة تُظهر تعليقاتها عبر Page.Annotations()، التي تُعيد AnnotationCollection. يغطي هذا الدليل إضافة التعليقات إلى صفحة، والتكرار وإزالتها، وقراءة التعليقات من مستند موجود، وإرفاق إجراءات الروابط، وتخصيص المظهر، وتسطح التعليقات.
إضافة تعليقات إلى صفحة
أنشئ مثيلًا ملموسًا للتعليق، وضعه باستخدام Rectangle، وأضفه إلى مجموعة الصفحة باستخدام AnnotationCollection.Add(). يمثل TextAnnotation تعليقًا على نمط الملاحظة اللاصقة مثبتًا على نقطة في الصفحة:
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/text_annotation.hpp>
#include <aspose/pdf/rectangle.hpp>
int main() {
Aspose::Pdf::Document doc("input.pdf");
auto& page = doc.Pages()[1];
Aspose::Pdf::Annotations::TextAnnotation note(doc);
note.Rect(Aspose::Pdf::Rectangle(100.0, 700.0, 200.0, 720.0, false));
note.Contents("Reviewed and approved");
page.Annotations().Add(note);
doc.Save("annotated.pdf");
}Annotation.Contents() / Contents(value) يحصلان على نص الملاحظة ويضبطانه، وAnnotation.Rect() / Rect(value) يحددان موقع التعليق على الصفحة.
التكرار وإزالة التعليقات
AnnotationCollection يدعم العد، الوصول بالفهرس، فحوصات العضوية، والإزالة بالقيمة أو بالفهرس:
#include <aspose/pdf/document.hpp>
int main() {
Aspose::Pdf::Document doc("input.pdf");
auto& annotations = doc.Pages()[1].Annotations();
std::cout << "Annotation count: " << annotations.Count() << "\n";
for (int i = 0; i < annotations.Count(); ++i) {
std::cout << "Contents: " << annotations[i].Contents() << "\n";
}
if (annotations.Count() > 0) {
annotations.Delete(0); // remove by index
}
annotations.Clear(); // remove everything
}AnnotationCollection.Contains(annotation) و Remove(annotation) يعملان على مرجع تعليقة محدد؛ Delete(index) يزيل بحسب الموقع، و Delete(annotation) يزيل تعليقة محددة دون الحاجة إلى فهرسها. IsReadOnly() يبلّغ ما إذا كان يمكن تعديل المجموعة.
قراءة التعليقات التوضيحية من مستند موجود
عند تحميل مستند، تكون التعليقات التوضيحية الخاصة به مُعبأة بالفعل ويمكن فحصها دون إضافة شيء. Annotation.AnnotationType() يبلّغ عن النوع الفرعي (AnnotationType::Text، AnnotationType::Highlight، AnnotationType::Link، AnnotationType::FreeText، AnnotationType::FileAttachment، AnnotationType::Watermark، وغيرها):
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/annotation_type.hpp>
int main() {
Aspose::Pdf::Document doc("annotated.pdf");
auto& annotations = doc.Pages()[1].Annotations();
for (int i = 0; i < annotations.Count(); ++i) {
auto& a = annotations[i];
if (a.AnnotationType() == Aspose::Pdf::Annotations::AnnotationType::Text) {
std::cout << "Note: " << a.Contents() << "\n";
}
}
}يتم الحفاظ على ترتيب التعليقات التوضيحية والنوع الفرعي عبر دورة حفظ/إعادة تحميل، لذا فإن الشيفرة التي تُدخل فهارس إلى Annotations() بعد تحميل المستند ترى نفس التسلسل الذي كان موجودًا عند كتابة الملف.
التعليقات التوضيحية للروابط والإجراءات
LinkAnnotation يرفق منطقة قابلة للنقر إلى صفحة ويُرسل PdfAction عند التفعيل. NamedAction ينتقل إلى هدف تنقل مُعرَّف مسبقًا، JavascriptAction ينفّذ سلسلة ECMAScript، وSubmitFormAction يرسل بيانات نموذج إلى URL عبر FileSpecification:
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/link_annotation.hpp>
#include <aspose/pdf/annotations/named_action.hpp>
#include <aspose/pdf/annotations/predefined_action.hpp>
#include <aspose/pdf/rectangle.hpp>
int main() {
Aspose::Pdf::Document doc;
auto page = doc.Pages().Add();
Aspose::Pdf::Annotations::LinkAnnotation link(
page, Aspose::Pdf::Rectangle(0.0, 0.0, 100.0, 20.0, false));
link.Action(Aspose::Pdf::Annotations::NamedAction(
Aspose::Pdf::Annotations::PredefinedAction::LastPage));
page.Annotations().Add(link);
doc.Save("linked.pdf");
}LinkAnnotation.Action(value) يقبل أي نوع فرعي PdfAction وينسخه داخليًا، لذا تحتفظ التعليقة بنسختها الخاصة من الإجراء. LinkAnnotation.Destination() / Destination(value) يحددان هدف تنقل صريح بدلاً من إجراء، وHighlighting() / Highlighting(value) يتحكمان في رد الفعل البصري المعروض أثناء النقر على الرابط.
مظهر التعليقة: الإطار، العلامات، واللون
كل Annotation يكشف عن Border، وهو حقل بت من AnnotationFlags، وColor يُستخدم لتصوير مظهره:
#include <aspose/pdf/annotations/border_style.hpp>
#include <aspose/pdf/annotations/annotation_flags.hpp>
#include <aspose/pdf/color.hpp>
// 'note' is an existing Annotation reference, e.g. from AnnotationCollection.
note.Border().Width(2);
note.Border().Style(Aspose::Pdf::Annotations::BorderStyle::Dashed);
note.Flags(Aspose::Pdf::Annotations::AnnotationFlags::Print);
note.Color(Aspose::Pdf::Color::Red());Border.Style() يقبل BorderStyle::Solid، Dashed، Beveled، Inset أو Underline. Border.Effect() يدعم أيضًا مخطط BorderEffect::Cloudy مع EffectIntensity() يتحكم في مدى وضوحه. AnnotationFlags هو حقل بت — ادمج القيم مثل Print، NoZoom، ReadOnly، وLockedContents للتحكم في سلوك التعليق التوضيحي في العارض دون تغيير محتواه المرئي.
تسطيح التعليقات التوضيحية
يمكن تسطيح تعليق توضيحي واحد — دمجه في محتوى الصفحة وجعله غير تفاعلي — عن طريق استدعاء Annotation.Flatten() مباشرةً:
#include <aspose/pdf/document.hpp>
int main() {
Aspose::Pdf::Document doc("annotated.pdf");
auto& annotations = doc.Pages()[1].Annotations();
for (int i = 0; i < annotations.Count(); ++i) {
annotations[i].Flatten();
}
doc.Save("flattened.pdf");
}لعمليات التعليقات التوضيحية على مستوى المستند كاملًا، يتبع PdfAnnotationEditor نمط Facade المشترك المستخدم عبر API: اربط مستند المصدر بـ BindPdf()، نفّذ عملية أو أكثر من عمليات التعليق التوضيحي، ثم اكتب النتيجة باستخدام Save():
#include <aspose/pdf/facades/pdf_annotation_editor.hpp>
int main() {
Aspose::Pdf::Facades::PdfAnnotationEditor editor;
editor.BindPdf("annotated.pdf");
editor.FlatteningAnnotations();
editor.Save("flattened.pdf");
}PdfAnnotationEditor.DeleteAnnotations() يزيل كل التعليقات التوضيحية من المستند المرتبط؛ DeleteAnnotations(annotType) يقتصر على إزالة AnnotationType واحد فقط. ImportAnnotationsFromXfdf(xfdfFile) وImportAnnotationsFromFdf(fdfFile) يحملان بيانات التعليق التوضيحي المصدرة من عارض PDF آخر.
نصائح وأفضل الممارسات
- دائمًا أضف التعليق التوضيحي المُنشأ حديثًا إلى
Page.Annotations()قبل استدعاءDocument.Save()— التعليق التوضيحي الذي لا يُضاف إلى مجموعة لن يُكتب في ملف الإخراج. - استخدم
AnnotationCollection.Contains(annotation)قبل استدعاءRemove()إذا لم تكن متأكدًا من أن التعليق لا يزال موجودًا؛Remove()تُعيدfalseبدلاً من إلقاء استثناء عندما يكون التعليق غير موجود. - تحقق من
Annotation.AnnotationType()قبل التحويل أو اتخاذ مسار بناءً على سلوك النوع الفرعي عند تكرار التعليقات التي تم تحميلها من ملف PDF غير موثوق أو من طرف ثالث. - قم بتسوية التعليقات باستخدام
Annotation.Flatten()(أوPdfAnnotationEditor.FlatteningAnnotations()للمستند بالكامل) قبل أرشفة المستند حتى يرى المراجعون في أدوات أخرى الشكل نفسه الذي أنشأته. AnnotationFlagsهو حقل بتات — اجمع العلامات مع القيم العددية الأساسية للعدد التعددي بدلاً من الافتراض أن علمًا واحدًا فقط يمكن أن يكون نشطًا في وقت واحد.
المشكلات الشائعة
| المشكلة | السبب | الإصلاح |
|---|---|---|
| التعليق غير مرئي بعد الحفظ | تم إنشاء التعليق ولكن لم يُضاف إلى Page.Annotations() | استدعِ page.Annotations().Add(annotation) قبل doc.Save() |
Remove() يُرجِع false | مرجع التعليق المُمرَّر لا يتطابق مع أي عنصر حالياً في المجموعة | استخدم Contains() أولاً، أو احذف عن طريق الفهرس باستخدام Delete(index) |
| نوع التعليق التوضيحي غير صحيح بعد إعادة التحميل | افترض الكود وجود نوع فرعي محدد دون التحقق من AnnotationType() | التفرّع على Annotation.AnnotationType() قبل معالجة الكائن كنوع فرعي محدد |
| يظهر أن إجراء الرابط غير مُعيّن بعد التعيين | انتهى نطاق PdfAction المحلي؛ LinkAnnotation.Action() تُعيد النسخة المستنسخة من التعليق التوضيحي، وليس الكائن الأصلي | اقرأ الإجراء مرة أخرى عبر link.Action() بدلاً من الاحتفاظ بالمتغيّر المحلي الأصلي |
عملية PdfAnnotationEditor لا تُحدث أي تأثير | لم يتم استدعاء BindPdf()، أو تم استدعاؤه بمسار غير موجود | تأكد من نجاح BindPdf() قبل استدعاء FlatteningAnnotations() أو DeleteAnnotations() |
FAQ
كيف يمكنني إضافة تعليق على شكل ملاحظة إلى صفحة PDF؟
أنشئ TextAnnotation مع الهدف Document، عيّن Rect() وContents() الخاصين به، ثم أضفه إلى page.Annotations() قبل الحفظ.
كيف يمكنني معرفة نوع التعليق التوضيحي الذي أنظر إليه؟
استدعِ Annotation.AnnotationType()، الذي يُعيد قيمة تعداد AnnotationType مثل Text، Link، Highlight، FreeText، FileAttachment، أو Watermark.
هل يمكن لتعليق توضيحي واحد أن يحمل أكثر من علم واحد؟
نعم. AnnotationFlags هو حقل بتات (Default، Invisible، Hidden، Print، NoZoom، ReadOnly، LockedContents، وغيرها)، لذا يمكن دمج عدة أعلام في تعليق توضيحي واحد.
ما الفرق بين تسطيح تعليق توضيحي واحد وتسطيح مستند كامل؟
Annotation.Flatten() يدمج تعليقًا توضيحيًا واحدًا في محتوى صفحته. PdfAnnotationEditor.FlatteningAnnotations() (يمكن تحديد نطاقه اختياريًا بنطاق الصفحات وAnnotationType عبر النسخة الزائدة التي تقبل start، end، وannotType) يقوم بتسطيح المستند المرتبط بالكامل في استدعاء واحد.
كيف يمكنني إزالة جميع التعليقات التوضيحية من نوع واحد من المستند؟
اربط المستند باستخدام PdfAnnotationEditor.BindPdf()، استدعِ DeleteAnnotations(annotType) مع الهدف AnnotationType، ثم Save() النتيجة.
API Reference ملخص
| الفئة/الطريقة | وصف |
|---|---|
Annotation | الفئة الأساسية المجردة لجميع الأنواع الفرعية للتعليقات التوضيحية لملفات PDF |
Annotation.Rect() / Rect(value) | احصل أو عيّن المستطيل المحيط بالتعليق |
Annotation.Contents() / Contents(value) | الحصول على أو تعيين محتوى نص annotation |
Annotation.AnnotationType() | إرجاع قيمة التعداد AnnotationType لهذا التوضيح |
Annotation.Flags() / Flags(value) | احصل أو عيّن حقل البت AnnotationFlags |
Annotation.Border() / Border(value) | احصل أو اضبط Border للتعليق التوضيحي |
Annotation.Color() / Color(value) | احصل أو اضبط عرض التعليق التوضيحي Color |
Annotation.Flatten() | يدمج هذا التوضيح في محتوى الصفحة، مما يجعله غير تفاعلي |
AnnotationCollection | مجموعة مرتبة من التعليقات التوضيحية على صفحة، تُرجع بواسطة Page.Annotations() |
AnnotationCollection.Add(annotation) / Add(annotation, considerRotation) | يضيف تعليقة إلى المجموعة |
AnnotationCollection.Count() | يعيد عدد التعليقات في المجموعة |
AnnotationCollection.Contains(annotation) | يُشير إلى ما إذا كانت المجموعة تحتوي على التعليقة المعطاة |
AnnotationCollection.Remove(annotation) | يزيل تعليقة محددة؛ يُعيد false إذا لم يتم العثور عليها |
AnnotationCollection.Delete(index) / Delete(annotation) | يزيل تعليقًا توضيحيًا حسب الفهرس أو حسب الإشارة |
AnnotationCollection.Clear() | يزيل جميع التعليقات التوضيحية من المجموعة |
TextAnnotation | تعليق بأسلوب الملاحظة اللاصقة مع Open() و Icon() (TextIcon) |
LinkAnnotation | منطقة قابلة للنقر تُرسل PdfAction عبر Action() / Action(value) |
LinkAnnotation.Destination() / Destination(value) | احصل أو عيّن هدف تنقل صريح |
HighlightAnnotation | يُعلِم جزءًا من النص بلون تسليط الضوء |
FreeTextAnnotation | يعرض ملاحظة نصية؛ يتم تكوينها عبر Justification()، DefaultAppearanceObject()، Callout() |
CircleAnnotation | يرسم إهليلجًا داخل مستطيل التعليق التوضيحي |
WatermarkAnnotation | تعليق تراكب مع Opacity() / Opacity(value) مستخرج |
WidgetAnnotation | تعليق مظهر حقل النموذج مع ReadOnly(), Required(), Exportable(), DefaultAppearance() |
NamedAction | إجراء تنقل مُعرّف مسبقًا (PredefinedAction enum) يمكن إرفاقه بـ LinkAnnotation |
JavascriptAction | ينفّذ سلسلة ECMAScript عبر Script() / GetECMAScriptString() |
SubmitFormAction | يرسل بيانات النموذج إلى عنوان URL FileSpecification عبر Url() / Url(value) |
Border | حدود التعليق مع Width(), Style() (BorderStyle), Effect() (BorderEffect) |
PdfAnnotationEditor | واجهة لاستيراد وتعديل وتسطير وحذف التعليقات على مستوى المستند |
PdfAnnotationEditor.FlatteningAnnotations() | يسطح التعليقات عبر المستند المرتبط |
PdfAnnotationEditor.DeleteAnnotations(annotType) | يحذف جميع التعليقات الخاصة بـ AnnotationType |
PdfAnnotationEditor.ImportAnnotationsFromXfdf(xfdfFile) | يستورد التعليقات التوضيحية من ملف XFDF |