基于MuPDF和Qt的PDF阅读器的开发
一、引言
设备上要渲染显示PDF文档,类似Adobe Reader、福昕阅读器等软件。如何去实现?Handling PDF这篇文档讨论介绍了在Qt应用程序中各种操作PDF的资料。从资料中看出,我们是要阅读渲染PDF文档到我们的设备中,关键还要能交叉编译移植到我们的设备上。在渲染显示方面整体给出三种方案:
- QtPDF(基于PDFium),不太好交叉编译。
- poppler-qt,与我们设备操作系统版本匹配的版本bug太多。
- muPDF,非常成熟,很多产品上都已使用,格式支持丰富,方便交叉编译。
最终选muPDF库来实现。
二、muPDF下载和编译
1、交叉编译iMX6-ARM版本
修改Makerules
...
157:
158: ifeq "$(OS)" "imx6-linux"
159: CCPATH = /opt/linaro-14.04/gcc-linaro-arm-linux-gnueabihf-4.8/bin
160: CC = $(CCPATH)/arm-linux-gnueabihf-gcc
161: LD = $(CCPATH)/arm-linux-gnueabihf-gcc
162: AR = $(CCPATH)/arm-linux-gnueabihf-ar
163: CROSSCOMPILE=yes
164: HAVE_GLUT := no
165: HAVE_PTHREAD := yes
166: SYS_PTHREAD_CFLAGS :=
167: SYS_PTHREAD_LIBS := -lpthread
168: HAVE_X11 := yes
169: SYS_X11_CFLAGS += -I/opt/linaro-14.04/usr/include
170: SYS_X11_LIBS += -L/opt/linaro-14.04/usr/lib/arm-linux-gnueabihf -lX11 -lXext -lxcb -lXau -lXdmcp -lpthread
171: endif
172:
...
执行命令:make generate && make OS=imx6-linux HAVE_GLUT=no -j32
最后源码目录的build/release/下生成四个库文件和多个二进制程序工具。libcurl.a libmupdf.a libmupdfthird.a libmuthreads.a mjsgen mujstest mupdf-x11 mupdf-x11-curl muraster mutool
使用的时候把四个库放到Qt工程里面使用,curl又依赖libcrypto.a库,所以去交叉编译工具链下找到libcrypto.a放进去。
2、编译win版本
用VS打开源码目录下的platform/win32/mupdf.sln,把所有工程中的属性--配置属性--C/C++--代码生成--运行库改为多线程调试DLL(/MDd)
编译mupdf生成三个库libmupdf.lib、libthirdparty.lib
,编译libresources工程,生成libresources.lib
,目前项目需要这三个库就够了。
三、使用muPDF库
其实重点在于如何使用muPDF库,这个库的API实在是难用,也没有帮助文档,只能看它提供的例子或这小工具的源码来学习。
先看工程目录结构:
main.cpp
mainwindow.h
mainwindow.cpp
mupdfdocument.h
mupdfdocument_p.h
mupdfdocument.cpp
mupdfpage.h
mupdfpage_p.h
mupdfpage.cpp
pagerender.h
pagerender.cpp
sequentialpagewidget.h
sequentialpagewidget.cpp
mupdfdocument:主要实现加载文档,提供文档信息功能。对mupdf接口封装主要实现在mupdfdocument_p里面;
mupdfpage和mupdfpage_p:主要实现渲染单个页面,输出QImage。主要难度在reanderImage函数;
pagerender:主要是借助QThread线程来渲染单个PDF页面;
sequentialpagewidget:实现对PDF文件显示的封装,如何做到高效显示,而又不占用太多资源?如何实现跳页?放大?缩小?滚动页面?非常小的屏幕下实现页码的正确显示?这里面都有所体现。
整个工程,都是短时间完成的,并且没有时间对muPDF做深入研究,所以肯定还有很多不足之处,还请见谅。整个工程代码没什么大的难度,难点在如何封装使用muPDF的API,以及如何使用Qt的控件更有效率的显示出来。
这是基于VS2013的PDFReader的工程。
资源工程下载
网友评论
1,include文件夹中的代码基本都是乱码,无法识别。需要用muPdf源码中的对应文件替换。
2,lib文件也有问题,编译时提示无法解析的符号之类的错误。
我自己用源码中的sln工程编译lib文件,但只能编译两个。libresource.lib无法编译成功,提示错误:
error C1091: 编译器限制: 字符串长度超过 65535 个字节
恳请博主指点。