博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在Qt中调用Mupdf库进行pdf显示
阅读量:5815 次
发布时间:2019-06-18

本文共 3509 字,大约阅读时间需要 11 分钟。

2018.5.10 更新内存对齐说明

感谢知乎网友@ 指出QImage处需要考虑内存对齐的问题。因为本人缺乏跨平台、图形库开发经验,所以在调试成功后就没有深入探究。
主要修改了QImage的构造方式,使用了指定bytesPerLine的构造函数,具体原因参见
孤独子狮的回答 - 知乎 https://www.zhihu.com/question/38594052/answer/387891545

前言

最近有个pdf的需求,Qt竟然没有显示pdf的api,着实令人郁闷。之后我尝试用了poppler,但是光配置编译工程就相当麻烦了,没有cmake等开源项目编译经验的人完全一脸懵逼。PDFium也是同理(手头上没有vpn也无法尝试)。感觉Mupdf编译器起来比较简单,所以就来用了一下。不过这个库有个缺点就是编译出来的文件太大了。

本人使用的版本是Mupdf1.12.0+Qt5.9.3+vs2015

下载Mupdf库

https://mupdf.com/downloads/

 

编译Mupdf

在mupdf-1.12.0-source\platform\win32目录下就有现成的mupdf.sln。

这里需要注意:这个工程默认使用的是/MT,而Qt MSVC默认用的是/MD,所以需要修改编译工程设置。我们这里只需要在编译工程中修改就可以了。

以下是一些有关QMake中设置运行库属性 /md /md /mt /mtd 的相关参考
http://blog.csdn.net/caoshangpa/article/details/51416077
http://www.cnblogs.com/codingmylife/archive/2010/05/08/1730832.html
http://www.voidcn.com/article/p-hhosrsia-hq.html

工程里默认生成的是都是静态库,请注意!

根据测试需要的分别是libmupdf.lib、libresources.lib、libthirdparty.lib这三个库(只使用了docs\examples\example.c的代码,使用别的函数可能需要再编译别的工程)

分别修改解决方案中的libmupdf、libthirdparty、libresources这三个工程,将debug下改成/MDd,release下改成/MD,编译即可得到这3个文件。其中libresources只有release版本的,所以debug模式下,我也引用这个文件。

当然你嫌麻烦或者还是不知道该怎么编译,可以去我的github直接下载编译好的静态库。

在Qt工程中引入Mupdf静态库

引入lib文件

新建一个工程,在工程的图标上右键——添加库——外部库。平台只勾选windows,链接选择静态,之后选择对应的库就可以了。(本人将debug与release编译的分别放在debug与release文件夹中)
添加包含目录
将Mupdf目录中的include复制到工程目录下(本人又新建了一个mupdf,将所有文件都放在里面了)
本人是这么写的,具体可以参考源代码:
INCLUDEPATH += $$PWD/mupdf/include/
之后运行QMake。

编写代码进行测试

代码是根据Mupdf中的案例文件example.c中的代码改写

#include "widget.h"#include "ui_widget.h"#include 
#include
#include
#include
#include
#include "mupdf/fitz.h"#include "mupdf/pdf.h"Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget){ ui->setupUi(this); char *input = const_cast< char* >("document.pdf"); float zoom, rotate; int page_number, page_count; fz_context *ctx; fz_document *doc; fz_pixmap *pix; fz_matrix ctm;//第一页为0 page_number=0; //100%缩放比 zoom=100; //旋转为0 rotate=0; //创建上下文 ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { qDebug()<
<<"cannot create mupdf context"; return; } //注册文档控制 fz_try(ctx) fz_register_document_handlers(ctx); fz_catch(ctx) { qDebug()<
<<"cannot register document handlers:"<< fz_caught_message(ctx); fz_drop_context(ctx); return; } //打开文档 fz_try(ctx) doc = fz_open_document(ctx, input); fz_catch(ctx) { qDebug()<
<< "cannot open document:"<< fz_caught_message(ctx); fz_drop_context(ctx); return; } //取得总的页数 fz_try(ctx) page_count = fz_count_pages(ctx, doc); fz_catch(ctx) { qDebug()<
<< "cannot count number of pages:"<< fz_caught_message(ctx); fz_drop_document(ctx, doc); fz_drop_context(ctx); return; } if (page_number < 0 || page_number >= page_count) { qDebug()<
<< "page number out of range: "<< page_number + 1<<"page count:"<
samples; int width = fz_pixmap_width(ctx, pix); int height = fz_pixmap_height(ctx, pix); QImage image(samples, width, height,pix->stride,QImage::Format_RGB888); QLabel *label=new QLabel; label->setPixmap(QPixmap::fromImage(image)); ui->layout->addWidget(label); // if (!image.save("a.png")) { // return; // } //回收内存 fz_drop_pixmap(ctx, pix); fz_drop_document(ctx, doc); fz_drop_context(ctx); } Widget::~Widget() { delete ui; }

参考代码 

https://github.com/blueroseslol/QtMupdf

 

找到一个之前有人封装的库,不过经过测试是无法成功编译的,不过可以参考一下mupdf库的用法。

https://github.com/xiangxw/mupdf-qt

别的参考:

http://blog.csdn.net/chenyijun/article/details/42582977

转载于:https://www.cnblogs.com/blueroses/p/8268217.html

你可能感兴趣的文章
在AngularJS中学习javascript的new function意义及this作用域的生成过程
查看>>
盘点物联网网关现有联网技术及应用场景
查看>>
mui 总结2--新建第一个app项目
查看>>
nginx的lua api
查看>>
考研太苦逼没坚持下来!看苑老师视频有点上头
查看>>
HCNA——RIP的路由汇总
查看>>
zabbix监控php状态(四)
查看>>
定时任务的创建
查看>>
实战Django:小型CMS Part2
查看>>
原创]windows server 2012 AD架构试验系列 – 16更改DC计算机名
查看>>
统治世界的十大算法
查看>>
linux svn安装和配置
查看>>
SSH中调用另一action的方法(chain,redirect)
查看>>
数据库基础
查看>>
表格排序
查看>>
关于Android四大组件的学习总结
查看>>
java只能的round,ceil,floor方法的使用
查看>>
由于无法创建应用程序域,因此未能执行请求。错误: 0x80070002 系统找不到指定的文件...
查看>>
新开的博客,为自己祝贺一下
查看>>
puppet任务计划
查看>>