如何用Leptonica将多页图像型PDF逐页读取为位图
图像型PDF逐页转位图并OCR的C API方案
Leptonica本身没有提供直接读取PDF的C API,但可以通过Poppler的C API实现图像型PDF的逐页位图提取,再结合Tesseract完成OCR,这是满足你需求的纯代码方案,无需依赖Shell命令。
实现步骤与示例代码
- 初始化Tesseract OCR引擎
- 用Poppler加载PDF文档,获取总页数
- 遍历每一页,将PDF页面渲染为Leptonica兼容的
Pix位图对象 - 将
Pix传入Tesseract执行OCR,处理结果 - 及时释放所有资源,避免内存泄漏
完整示例代码:
#include <tesseract/baseapi.h> #include <leptonica/allheaders.h> #include <poppler.h> #include <cairo.h> int main() { // 初始化Tesseract引擎 tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI(); if (api->Init(NULL, "eng")) { fprintf(stderr, "初始化Tesseract失败\n"); exit(1); } // 加载目标PDF文件 GError *error = NULL; // 注意路径需转为file://格式,本地路径示例:file:///home/user/test.pdf PopplerDocument *pdf_doc = poppler_document_new_from_file("file:///path/to/your/pdf/file.pdf", NULL, &error); if (!pdf_doc) { fprintf(stderr, "加载PDF失败: %s\n", error->message); g_error_free(error); exit(1); } int total_pages = poppler_document_get_n_pages(pdf_doc); for (int page_idx = 0; page_idx < total_pages; page_idx++) { // 获取当前页 PopplerPage *page = poppler_document_get_page(pdf_doc, page_idx); if (!page) continue; // 获取页面尺寸,按300DPI渲染(PDF默认DPI为72) double page_w, page_h; poppler_page_get_size(page, &page_w, &page_h); int render_w = page_w * 300 / 72; int render_h = page_h * 300 / 72; // 创建Cairo表面用于渲染 cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, render_w, render_h); cairo_t *cr = cairo_create(surface); cairo_scale(cr, 300.0 / 72.0, 300.0 / 72.0); // 缩放至目标DPI poppler_page_render(page, cr); // 将Cairo表面转为Leptonica的Pix对象 Pix *page_pix = pixCreateFromCairoSurface(surface); if (page_pix) { // 传入Tesseract执行OCR api->SetImage(page_pix); char *ocr_result = api->GetUTF8Text(); printf("第%d页OCR结果:\n%s\n", page_idx + 1, ocr_result); // 释放OCR结果内存 delete[] ocr_result; pixDestroy(&page_pix); } // 释放当前页相关资源 cairo_destroy(cr); cairo_surface_destroy(surface); g_object_unref(page); } // 释放全局资源 g_object_unref(pdf_doc); api->End(); delete api; return 0; }
编译与依赖说明
编译时需要链接Tesseract、Leptonica和Poppler的相关库,示例编译命令:
g++ -o pdf_ocr pdf_ocr.cpp `pkg-config --cflags --libs tesseract lept poppler-glib`
替代方案
如果无法使用Poppler,也可以选择MuPDF的C API,它同样支持逐页提取PDF中的位图,并提供了转为Leptonica Pix对象的接口,适配逻辑与上述方案类似。
内容的提问来源于stack exchange,提问作者Dov
相关产品推荐
相关产品推荐

