چگونه با اسناد PDF در C++ کار کنیم

چگونه با اسناد PDF در C++ کار کنیم

Aspose.PDF FOSS برای C++ یک کتابخانهٔ C++20 است که تحت مجوز MIT و بدون وابستگی ارائه می‌شود، با CMake ساخته و لینک می‌شود — نیازی به افزودن واردات از مدیر بسته نیست. این راهنما جریان کاری اصلی مبتنی بر Document را مرور می‌کند: باز کردن یک PDF موجود، بررسی صفحات و فراداده‌ها، استخراج متن، و رندر یک صفحه به تصویر رستری.

راهنمای گام به گام

گام 1: نصب بسته

مخزن را کلون کنید و به پروژهٔ CMake خود به‌عنوان زیرپوشه اضافه کنید:

git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp.git
add_subdirectory(Aspose.PDF-FOSS-for-Cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)

یا آن را به‌صورت مستقل پیکربندی و ساخت کنید:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

اطمینان حاصل کنید ابزار زنجیرهٔ ساخت حل می‌شود با کامپایل یک برنامهٔ حداقل در برابر سرآیندها:

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

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

یک ساخت موفق که pages: 0 را برای Document تازه ساخته‌شده و خالی چاپ می‌کند، تأیید می‌کند که کتابخانه به‌درستی لینک شده است.


مرحله ۲: وارد کردن کلاس‌های مورد نیاز

#include <aspose/pdf/document.hpp>
#include <aspose/pdf/document_info.hpp>
#include <aspose/pdf/page.hpp>
#include <aspose/pdf/page_collection.hpp>
#include <aspose/pdf/text_absorber.hpp>
#include <aspose/pdf/bmp_device.hpp>
#include <aspose/pdf/resolution.hpp>
#include <fstream>
#include <iostream>

مرحله ۳: باز کردن یک سند PDF و شمارش صفحات آن

یک Document را از مسیر فایل برای باز کردن یک PDF موجود بسازید. Document::Pages() مقدار PageCollection را برمی‌گرداند و Count() تعداد صفحاتی که دارد را گزارش می‌کند:

Aspose::Pdf::Document doc("input.pdf");
std::cout << "Page count: " << doc.Pages().Count() << "\n";

مرحله ۴: خواندن متادیتای سند

Document::Info() یک شیء DocumentInfo را برمی‌گرداند که دسترسی‌گرهای خواندن/نوشتن تایپ‌شده برای ورودی‌های استاندارد دیکشنری /Info دارد:

auto& info = doc.Info();
std::cout << "Title: "    << info.Title()    << "\n";
std::cout << "Author: "   << info.Author()   << "\n";
std::cout << "Producer: " << info.Producer() << "\n";

مرحله ۵: استخراج متن از یک صفحه

Aspose::Pdf::Text::TextAbsorber یک Document یا یک Page تک را پیمایش می‌کند و متنی که می‌بیند را جمع‌آوری می‌نماید؛ Text() پس از آن نتیجه را برمی‌گرداند. PageCollection به صورت 1-ایندکس است، بنابراین Pages()[1] اولین صفحه است:

auto page = doc.Pages()[1];

Aspose::Pdf::Text::TextAbsorber absorber;
absorber.Visit(page);
std::cout << absorber.Text() << "\n";

Visit() همچنین Document کامل را به‌صورت مستقیم (absorber.Visit(doc)) می‌پذیرد وقتی می‌خواهید متن تمام صفحات را به‌هم پیوسته داشته باشید به‌جای یک صفحهٔ منفرد.


مرحله 6: رندر صفحه به تصویر رستری

BmpDevice یک Page را به تصویر BMP بدون فشرده‌سازی رندر می‌کند. سازندهٔ آن یک Resolution می‌گیرد که DPI خروجی را کنترل می‌کند، و Process() بایت‌های رندر شده را به هر std::ostream می‌نویسد:

Aspose::Pdf::Devices::BmpDevice device(Aspose::Pdf::Devices::Resolution(150));

std::ofstream imageOut("page1.bmp", std::ios::binary);
device.Process(page, imageOut);

مرحله 7: به‌روزرسانی فراداده و ذخیرهٔ سند

Setterهای موجود در DocumentInfo تغییراتی را مرحله‌بندی می‌کنند که در بار بعدی که Save() بر روی Document مالک اجرا می‌شود، اعمال می‌شوند:

doc.Info().Title("Processed by Aspose.PDF FOSS for C++");
doc.Save("output.pdf");

مشکلات رایج و راه‌حل‌ها

Accessing Pages()[0] throws std::out_of_range

PageCollection یک‌پایه است، که با معنای Aspose.PDF استاندارد مطابقت دارد — صفحهٔ اول Pages()[1] است. یک اندیس کمتر از 1 یا بالاتر از Count() خطا می‌اندازد.

TextAbsorber::Text() یک رشته خالی برمی‌گرداند

Text() هرچه توسط آخرین فراخوانی Visit() جمع‌آوری شده بود را برمی‌گرداند. تأیید کنید که Visit() واقعاً قبل از خواندن Text() فراخوانی شده است، و اینکه صفحه یا سندی که بازدید کردید شامل متن قابل استخراج باشد نه فقط تصاویر اسکن‌شده.

فایل BMP رندر شده به‌طور غیرمنتظره‌ای کوچک است یا خالی به‌نظر می‌رسد

یک مقدار پایین Resolution یک تصویر رستری کوچک تولید می‌کند. DPI پاس‌داده شده به Resolution را افزایش دهید — برای مثال، Resolution(300) برای خروجی با کیفیت چاپ — و تأیید کنید که اندیس صفحهٔ پاس‌داده شده به Process() همان چیزی است که قصد داشتید.

DocumentInfo فیلدها به‌عنوان رشته‌های خالی خوانده می‌شوند

همهٔ تولیدکنندگان PDF ورودی‌های استاندارد /Info را نمی‌نویسند. قبل از این‌که فرض کنید استخراج متادیتا شکست خورده است، مقادیر خالی Producer() و Creator() را بررسی کنید — یک رشتهٔ خالی نتیجهٔ تعریف‌شده برای کلید غیرباوجود است.

تغییرات اعمال‌شده با Info().Title(...) در فایل ذخیره‌شده ظاهر نمی‌شوند

تغییرات DocumentInfo در حافظه آماده می‌شوند و فقط در بار بعدی که Save() روی همان نمونه Document اجرا شود، ذخیره می‌شوند. اطمینان حاصل کنید که ویرایش متادیتا قبل از Save() انجام شود، نه بعد از آن.

سوالات متداول

آیا اندیس‌گذاری صفحات در Aspose.PDF FOSS برای C++ صفر-مبنا است یا یک-مبنا؟

یک-مبنا. doc.Pages()[1] همیشه صفحه اول است.

آیا TextAbsorber می‌تواند متن را از یک صفحه به‌جای کل سند استخراج کند؟

بله. Visit() به‌صورت اضافه‌بار (overloaded) طراحی شده است تا یا یک Document را بپذیرد — که متن تمام صفحات را استخراج می‌کند — یا یک Page منفرد، که فقط متن همان صفحه را استخراج می‌کند.

آیا اگر فقط داده‌ها را از سند بخوانم، نیاز به فراخوانی Save() دارم؟

خیر. Save() فقط پس از تغییراتی که نیاز به نوشتن دوباره در فایل دارند، مانند ویرایش فیلدهای DocumentInfo، لازم است. خواندن تعداد صفحات، استخراج متن یا رندر کردن یک صفحه، سند را تغییر نمی‌دهد.

چگونه می‌توانم وضوح صفحه رندر شده را کنترل کنم؟

یک مقدار Resolution را به سازندهٔ دستگاه پاس دهید — برای مثال، Resolution(150) برای 150 DPI. مقادیر بالاتر تصاویر رستر بزرگتر و با دقت بالاتری تولید می‌کنند.

قالبی که BmpDevice تولید می‌کند چیست؟

یک تصویر BMP فشرده‌نشده که مستقیماً به std::ostream که به Process() پاس داده شده نوشته می‌شود.

همچنین ببینید:

 فارسی