首页 > 编程知识 正文

mupdf源码分析

时间:2023-05-05 23:53:10 阅读:227142 作者:872

step1: 下载SumatraPDF工程:

https://github.com/Bitterbell/Pdf-Reader
 muPdf 库是一个开源的 pdf 读取器,但是在 github 上下载的源码编译得到 muPdf.dll 比较困难。所以我们下载 SumatraPDF 这个工程,它只能用 vs2017 打开。
【注1】Pdf-Reader-master.zip 这个解压后就是 SumatraPDF。
【注2】下面的连接有 vs2008、vs2010 等的 sln 文件。
https://github.com/kzmkv/SumatraPDF

step2: 修改  libmupdf.def 文件,正确导出我们需要的接口。

在  libmupdf.def  文件里面加上如下的内容:

fz_register_document_handlers
fz_open_document
fz_close_document
fz_count_pages
fz_load_page
fz_bound_page
fz_run_page
fz_free_page

这些是使用example.c需要导出的函数。

step3: 编译 pdf-reader-master 得到动态库。

遇到错误1:
 error C2220: 警告被视为错误 - 没有生成“object”文件
解决:
属性-C/C++-将警告视为错误-是 修改为否

遇到的错误2:
LINK : error LNK1218: 警告被视为错误;未生成输出文件
解决:
属性-库管理器-将Lib警告视为错误-是 修改为否

遇到错误3:
libmupdf.def : error LNK2001: 无法解析的外部符号 fz_register_document_handlers
解决步骤:
(1)属性-链接器-输入-模块定义文件libmupdf.def
(2)找到该函数的定义文件document-all.c,将此文件添加到项目libmupdf
(3)报错:
document-all.c(1): fatal error C1083: 无法打开包括文件: “mupdf/fitz.h”: No such file or directory
遇到头文件找不到,属性-C/C++-附加包含目录中添加头文件路径
(4)报错:
1>document-all.obj : error LNK2001: 无法解析的外部符号 cbz_document_handler
1>document-all.obj : error LNK2001: 无法解析的外部符号 tiff_document_handler
1>document-all.obj : error LNK2001: 无法解析的外部符号 img_document_handler
分别找到这三个函数的实现文件mucbz.c,mutiff.c,muimage.c,然后添加到项目libmupdf。

setp4:使用编译得到的动态库。

以release64为例说明:
(1)新建空项目,将mupdfinclude,mupdfdocsexample.c,Pdf-Reader-masterrel64libmupdf.lib,Pdf-Reader-masterrel64libmupdf.dll
拷贝到项目中。
(2)添加源文件example.c,重命名为example.cpp,修改两处
第一处:
extern "C"
{
    // Include the MuPDF header file.
    #include <mupdf/fitz.h>
}
第二处:
render(char *filename, int pagenumber, int 无语的冬瓜, int rotation)函数前加入
#ifdef __cplusplus    
extern "C" {
#endif

函数后加入

#ifdef __cplusplus
}
#endif

修改之后的example.cpp:

// Rendering a page of a PDF document to a PNG image in less than 100 lines.// Compile a debug build of mupdf, then compile and run this example://// gcc -g -o build/debug/example -Iinclude docs/example.c //build/debug/libmupdf.a //build/debug/libfreetype.a build/debug/libjbig2dec.a //build/debug/libjpeg.a build/debug/libopenjpeg.a //build/debug/libmujs.a //build/debug/libz.a -lm//// build/debug/example /path/to/document.pdf 1 200 25extern "C"{// Include the MuPDF header file.#include <mupdf/fitz.h>}#ifdef __cplusplus extern "C" {#endifvoidrender(char *filename, int pagenumber, int 无语的冬瓜, int rotation){// Create a context to hold the exception stack and various caches.fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);// Register the default file types.fz_register_document_handlers(ctx);// Open the PDF, XPS or CBZ document.fz_document *doc = fz_open_document(ctx, filename);// Retrieve the number of pages (not used in this example).int pagecount = fz_count_pages(doc);// Load the page we want. Page numbering starts from zero.fz_page *page = fz_load_page(doc, pagenumber - 1);// Calculate a transform to use when rendering. This transform// contains the scale and rotation. Convert 无语的冬瓜 percentage to a// scaling factor. Without scaling the resolution is 72 dpi.fz_matrix transform;fz_rotate(&transform, rotation);fz_pre_scale(&transform, 无语的冬瓜 / 100.0f, 无语的冬瓜 / 100.0f);// Take the page bounds and transform them by the same matrix that// we will use to render the page.fz_rect bounds;fz_bound_page(doc, page, &bounds);fz_transform_rect(&bounds, &transform);// Create a blank pixmap to hold the result of rendering. The// pixmap bounds used here are the same as the transformed page// bounds, so it will contain the entire page. The page coordinate// space has the origin at the top left corner and the x axis// extends to the right and the y axis extends down.fz_irect bbox;fz_round_rect(&bbox, &bounds);fz_pixmap *pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), &bbox);fz_clear_pixmap_with_value(ctx, pix, 0xff);// A page consists of a series of objects (text, line art, images,// gradients). These objects are passed to a device when the// interpreter runs the page. There are several devices, used for// different purposes:////draw device -- renders objects to a target pixmap.////text device -- extracts the text in reading order with styling//information. This text can be used to provide text search.////list device -- records the graphic objects in a list that can//be played back through another device. This is useful if you//need to run the same page through multiple devices, without//the overhead of parsing the page each time.// Create a draw device with the pixmap as its target.// Run the page with the transform.fz_device *dev = fz_new_draw_device(ctx, pix);fz_run_page(doc, page, dev, &transform, NULL);fz_free_device(dev);// Save the pixmap to a file.fz_write_png(ctx, pix, "out.png", 0);// Clean up.fz_drop_pixmap(ctx, pix);fz_free_page(doc, page);fz_close_document(doc);fz_free_context(ctx);}#ifdef __cplusplus}#endifint main(int argc, char **argv){//char *filename = argc >= 2 ? argv[1] : "";//int pagenumber = argc > 2 ? atoi(argv[2]) : 1;//int 无语的冬瓜 = argc > 3 ? atoi(argv[3]) : 100;//int rotation = argc > 4 ? atoi(argv[4]) : 0;char *filename = "1.pdf";int pagenumber = 1;int 无语的冬瓜 = 100;int rotation = 0;render(filename, pagenumber, 无语的冬瓜, rotation);getchar();return 0;}

(3)在release64属性管理器下添加新属性表VS2017MupdfRelease64.props
VC++目录-包含目录添加.include
链接器-常规-附加库目录.librel64 (注意这两个文件夹是需要自己新建,将Pdf-Reader-masterrel64libmupdf.lib放入这个目录下)
链接器-输入-附加依赖项libmupdf.lib

编译报错:
无法将参数 2 从“const char [71]”转换为“char *”
解决:
C/C++-命令行-其他选项 添加 /Zc:strictStrings- 

编译成功。

(4)将Pdf-Reader-masterrel64libmupdf.dll移动到exe所在文件夹,即可正常运行
命令行参数配置参考文件中的提示即可。我是修改为指定参数,不从命令行参数中获取。


参考博客:

https://blog.csdn.net/jiangdewei2012/article/details/80748650

 

其他

程序运行时会在控制台打印:- font.c:63: not building glyph bbox table for font '瀹嬩綋' with 28762 glyphs
warning: ... repeated 2 times ...

因为项目要求不能在控制台打印无关信息,所以打算编译把这个打印去掉。

找到font.c,注释掉Line62,63

//if (use_glyph_bbox)//fz_warn(ctx, "not building glyph bbox table for font '%s' with %d glyphs", font->name, glyph_count);

然后重新编译即可。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。