在MuPDF(C语言)中如何将路径绘制到PDF的指定现有页面?
在MuPDF(C语言)中如何将路径绘制到PDF的指定现有页面?
看起来你已经走对了创建路径的流程,但在MuPDF中修改现有PDF页面和新建页面的设备关联逻辑完全不同。核心问题是你需要用专门的PDF写入设备,并且必须先重放原页面内容(否则原有内容会被覆盖)。下面是完整的修正实现和关键步骤解析:
核心思路
MuPDF修改现有页面的正确流程是:
- 加载目标页面并获取其媒体框(MediaBox)
- 创建关联该页面的PDF写入设备(而非通用设备)
- 先将原页面的所有内容重放到设备上(保留原有内容)
- 在设备上绘制新的路径
- 完成页面写入并释放所有资源
修正后的完整代码
#include "mupdf/fitz.h" #include "mupdf/pdf.h" void DrawPathOnPage(fz_context* ctx, pdf_document* dst_doc, int dst_page_num) { // Draws a path in page #dst_page_num of the opened dst_doc. fz_path* path = NULL; pdf_page* page = NULL; fz_device* dev = NULL; // === 1. 创建要绘制的路径 === path = fz_new_path(ctx); float x0 = 0; float y0 = 0; float x1 = 100; float y1 = 100; fz_rectto(ctx, path, x0, y0, x1, y1); fz_closepath(ctx, path); // 闭合路径(只需要调用一次) // === 2. 加载目标页面并获取媒体框 === page = pdf_load_page(ctx, dst_doc, dst_page_num); fz_rect mediabox = pdf_page_bound_box(ctx, page, PDF_BOUND_MEDIA); // === 3. 关联设备与现有页面(解决你的(Q)问题) === // 使用pdf_begin_page_write创建专用于修改页面的设备 // 参数说明:上下文、目标文档、要修改的页面、页面媒体框、是否保留原页面资源(1=保留) dev = pdf_begin_page_write(ctx, dst_doc, page, mediabox, 1); // === 4. 重放原页面内容(必须!否则原有内容会丢失) === fz_matrix ctm = fz_identity; // 用单位矩阵保持原页面的缩放比例 pdf_run_page(ctx, page, dev, ctm, NULL); // === 5. 在设备上绘制新路径 === float alpha = 0.9f; int even_odd = 0; // 填充规则:0=非零环绕,1=奇偶规则 float color[3] = {0.75f, 0.75f, 0.75f}; // RGB灰色 fz_fill_path( ctx, dev, path, even_odd, ctm, // 可根据需求调整变换矩阵(缩放、旋转等) fz_device_rgb(ctx), // 颜色空间设备 color, alpha, fz_default_color_params ); // === 6. 完成页面写入并释放所有资源 === pdf_end_page_write(ctx, dst_doc, page, dev); // 提交页面修改 fz_drop_device(ctx, dev); fz_drop_page(ctx, page); fz_drop_path(ctx, path); }
关键细节说明
为什么要重放原页面?
MuPDF的页面写入设备是基于"重建页面内容"的逻辑,它不会自动保留原有页面的内容。必须通过pdf_run_page将原页面的所有内容渲染到设备上,再叠加新内容,才能保证最终页面同时包含原有内容和你的新路径。pdf_begin_page_write的作用
这个函数是MuPDF专门为修改现有页面设计的API,它会:- 创建一个关联目标页面的写入设备
- 保留原页面的资源(字体、图片等),避免重复存储
- 确保新内容的坐标系统与原页面一致
资源释放注意事项
MuPDF采用手动内存管理,所有通过fz_new_*、pdf_load_*创建的对象,必须用对应的fz_drop_*、pdf_drop_*函数释放,否则会导致内存泄漏。扩展说明
- 如果你需要绘制描边路径而非填充,可以用
fz_stroke_path替代fz_fill_path,并设置线宽、线帽等属性 - 颜色空间可以切换为CMYK(
fz_device_cmyk(ctx))或灰度(fz_device_gray(ctx)),对应的color数组长度需要调整(CMYK为4个元素,灰度为1个) - 修改完成后,记得调用
pdf_save_document(ctx, dst_doc, NULL)将更改保存到磁盘(如果目标文档是从磁盘加载的)
- 如果你需要绘制描边路径而非填充,可以用
内容来源于stack exchange
相关产品推荐
相关产品推荐

