基于MuPDF库实现PDF文件转换成PNG格式图片

LOSER

发布日期: 2018-11-06 22:31:04 浏览量: 743
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

背景

之所以会接触MuPDF是因为,有位群友在Q群里提问,如何将PDF保存为.PNG图片格式。我一看到这个问题,就蒙了,因为我没有接触过类似的项目或程序。但是,作为一群之主的我,还是要给初学者一个答复的,所以便去网上搜索了相关信息,才了解到有MuPDF开源库的存在。

MuPDF是一种轻量级的PDF,XPS和电子书阅读器。由各种平台的软件库,命令行工具和查看器组成。支持许多文档格式,如PDF,XPS,OpenXPS,CBZ,EPUB和FictionBook 2。

后来,自己就根据网上搜索到的一些资料,实现了基于MuPDF库将PDF指定页转换成PNG格式图片的小程序。现在,我就把程序的实现思路和过程写成文档,分享给大家。

实现思路

对于MuPDF库的源码下载以及编译过程,可以参考本站的《使用VS2013编译MuPDF库》这篇文章。

其实,在MuPDF库中就提供了这一个功能:将PDF指定页转换成PNG格式图片,所以,我们直接编译MuPDF提供的代码就可以了。

示例程序代码位于MuPDF库源码的“docs”目录下的“example.c”文件,我们只需使用VS2013创建一个空项目,然后把“example.c”文件导入项目中,接着将“include”目录中的头文件以及编译出来的libmupdf.lib、libmupdf-js-none.lib、libthirdparty.lib导入文件中即可。

其中,“example.c”中主要的函数就是 render 函数,我们主要是把参数传进render函数,就可以把pdf转换成png图片了。

对于“example.c”的代码可以不用修改,直接编译运行即可。但是,为了方便演示,我们还是对“example.c”中的 main 函数进行修改。

编码实现

以下是“example.c”文件中 render 函数的源码:

  1. void render(char *filename, int pagenumber, int zoom, int rotation)
  2. {
  3. // Create a context to hold the exception stack and various caches.
  4. fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
  5. // Open the PDF, XPS or CBZ document.
  6. fz_document *doc = fz_open_document(ctx, filename);
  7. // Retrieve the number of pages (not used in this example).
  8. int pagecount = fz_count_pages(doc);
  9. // Load the page we want. Page numbering starts from zero.
  10. fz_page *page = fz_load_page(doc, pagenumber - 1);
  11. // Calculate a transform to use when rendering. This transform
  12. // contains the scale and rotation. Convert zoom percentage to a
  13. // scaling factor. Without scaling the resolution is 72 dpi.
  14. fz_matrix transform;
  15. fz_rotate(&transform, rotation);
  16. fz_pre_scale(&transform, zoom / 100.0f, zoom / 100.0f);
  17. // Take the page bounds and transform them by the same matrix that
  18. // we will use to render the page.
  19. fz_rect bounds;
  20. fz_bound_page(doc, page, &bounds);
  21. fz_transform_rect(&bounds, &transform);
  22. // Create a blank pixmap to hold the result of rendering. The
  23. // pixmap bounds used here are the same as the transformed page
  24. // bounds, so it will contain the entire page. The page coordinate
  25. // space has the origin at the top left corner and the x axis
  26. // extends to the right and the y axis extends down.
  27. fz_irect bbox;
  28. fz_round_rect(&bbox, &bounds);
  29. fz_pixmap *pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), &bbox);
  30. fz_clear_pixmap_with_value(ctx, pix, 0xff);
  31. // A page consists of a series of objects (text, line art, images,
  32. // gradients). These objects are passed to a device when the
  33. // interpreter runs the page. There are several devices, used for
  34. // different purposes:
  35. //
  36. // draw device -- renders objects to a target pixmap.
  37. //
  38. // text device -- extracts the text in reading order with styling
  39. // information. This text can be used to provide text search.
  40. //
  41. // list device -- records the graphic objects in a list that can
  42. // be played back through another device. This is useful if you
  43. // need to run the same page through multiple devices, without
  44. // the overhead of parsing the page each time.
  45. // Create a draw device with the pixmap as its target.
  46. // Run the page with the transform.
  47. fz_device *dev = fz_new_draw_device(ctx, pix);
  48. fz_run_page(doc, page, dev, &transform, NULL);
  49. fz_free_device(dev);
  50. // Save the pixmap to a file.
  51. fz_write_png(ctx, pix, "out.png", 0);
  52. // Clean up.
  53. fz_drop_pixmap(ctx, pix);
  54. fz_free_page(doc, page);
  55. fz_close_document(doc);
  56. fz_free_context(ctx);
  57. }

程序测试

我们修改 main 函数直接调用上述函数接口, main 函数为:

  1. int main(int argc, char **argv)
  2. {
  3. // 文件路径
  4. char filename[MAX_PATH] = "C:\\Users\\DemonGan\\Desktop\\test.pdf";
  5. // 转换的页码数
  6. int pagenumber = 1;
  7. // 缩放比例
  8. int zoom = 100;
  9. // 旋转角度
  10. int rotation = 0;
  11. // 处理
  12. render(filename, pagenumber, zoom, rotation);
  13. system("pause");
  14. return 0;
  15. }

直接运行程序,目录下有 out.png 图片生成,打开图片查看内容,发现是 test.pdf 的第一页内容,所以转换成功。

总结

这个程序的实现,自己可以不用写代码就可以完成。因为MuPDF已经把接口都封装好了,而且也有示例程序可以直接调用。如果想要把界面做得更有好些,可以把程序写成界面程序,然后直接调用现在的这个 render 函数接口,进行转换即可。

上传的附件 cloud_download Pdf2Png_Test.7z ( 10.16mb, 11次下载 )

keyboard_arrow_left上一篇 : 大数据 16、分类算法 -Softmax 把修改/更新过的项目重新提交至github上 : 下一篇keyboard_arrow_right



LOSER
2018-11-06 22:31:24
使用MuPDF库实现PDF文件转换成PNG格式图片
BIGMAN
2019-03-10 15:37:34
很详细
小杰
2019-05-15 14:54:31
楼主 使用的mupdf 版本是多少。 方便提供下么? 谢谢 我这边使用的版本 头文件编译存在问题 , 想自己编32 64 位的

发送私信

越是憧憬,越要风雨兼程

7
文章数
9
评论数
最近文章
eject