在Qt中调用Mupdf库进行pdf显示
2018.5.10 更新内存对齐说明
前言
最近有个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 <QMessageBox>
- #include <QDebug>
- #include <QImage>
- #include <QPixmap>
- #include <QLabel>
- #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=;
- //旋转为0
- rotate=;
- //创建上下文
- ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
- if (!ctx)
- {
- qDebug()<<stderr<<"cannot create mupdf context";
- return;
- }
- //注册文档控制
- fz_try(ctx)
- fz_register_document_handlers(ctx);
- fz_catch(ctx)
- {
- qDebug()<<stderr<<"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()<<stderr<< "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()<<stderr<< "cannot count number of pages:"<< fz_caught_message(ctx);
- fz_drop_document(ctx, doc);
- fz_drop_context(ctx);
- return;
- }
- if (page_number < || page_number >= page_count)
- {
- qDebug()<<stderr<< "page number out of range: "<< page_number + <<"page count:"<<page_count;
- fz_drop_document(ctx, doc);
- fz_drop_context(ctx);
- return;
- }
- //计算缩放以及旋转
- fz_scale(&ctm, zoom / , zoom / );
- fz_pre_rotate(&ctm, rotate);
- //渲染pixmap
- fz_try(ctx)
- pix = fz_new_pixmap_from_page_number(ctx, doc, page_number, &ctm, fz_device_rgb(ctx), );
- fz_catch(ctx)
- {
- qDebug()<<stderr<< "cannot render page: %s\n"<< fz_caught_message(ctx);
- fz_drop_document(ctx, doc);
- fz_drop_context(ctx);
- return;
- }
- //渲染成图片
- // unsigned char *samples = fz_pixmap_samples(ctx, pix);
- unsigned char *samples = pix->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
在Qt中调用Mupdf库进行pdf显示的更多相关文章
- Qt中调用PolarSSL库(一)
最近一直在学习SSL相关的知识,也是先了解理论相关的知识,主要是SSL相关的基本概念和连接建立过程,主要是基于PolarSSL开源库进行学习.学习完了之后就希望能给有所运用,就想用Qt写一个简单的程序 ...
- discuz x3在DIY模块中调用伪静态不成功,显示动态链接的解决办法
discuz x3在DIY模块中调用伪静态不成功,显示动态链接,然而其他的链接正常显示伪静态. 后台启用伪静态后,发现论坛版块.帖子点击链接,伪静态正常显示,然后在门户首页DIY显示的帖子,点进去后发 ...
- Java乔晓松-android中调用系统拍照功能并显示拍照的图片
android中调用系统拍照功能并显示拍照的图片 如果你是拍照完,利用onActivityResult获取data数据,把data数据转换成Bitmap数据,这样获取到的图片,是拍照的照片的缩略图 代 ...
- Qt中添加OpenCV库
配置在Qt中的OpenCV,看了很多“教程”,最终成功.记一下过程. 本机配置: window7 32位系统: qt-opensource-windows-x86-mingw492-5.5.1: Op ...
- iOS开发:在Swift中调用oc库
先列举这个工程中用到的oc源码库: MBProgressHUD:半透明提示器,Loading动画等 SDWebImage:图片下载和缓存的库 MJRefresh: 下拉刷新,上拉加载 Alamofir ...
- QT中使用Glut库
用Qt中的QGLWidget窗体类中是不包括glut工具库的,难怪在myGLWidget(在我的程序中是QGLWidget的派生类)中绘制实心球体是说“glutSolidSphere”: 找不到标识符 ...
- Qt中使用OpenCV库
原地址:http://blog.sina.com.cn/s/blog_5c70dfc80100qwi3.html 心情真是好啊,曾经一度想放弃使用Qt加OpenCV进行数字图像处理了,幸好坚持住了,今 ...
- Qt中使用Boost库
关于boost库的编译,请看https://www.cnblogs.com/HackerArt/p/10539516.html 网上可以查到很多介绍qt使用库文件的教程,但是大多都没有注意到,qt中支 ...
- Unity中调用DLL库
DLL -- Dynamic Link Library(动态链接库文件),这里以Window平台为例. Unity支持的两种语言生成的DLL库(C++.C#),这里以C#为例,C++网上可以搜索很详细 ...
随机推荐
- 直径上的乱搞 bzoj1999求树直径上的结点+单调队列,bzoj1912负权树求直径+求直径边
直径上的乱搞一般要求出这条直径上的点集或者边集 bzoj1999:对直径上的点集进行操作 /* 给出一颗树,在树的直径上截取长度不超过s的路径 定义点u到s的距离为u到s的最短路径长度 定义s的偏心距 ...
- CF558E
非常好的一道题,是线段树的常见玩法 将字符串转化为1~26个数 对区间开一棵线段树,用两个数组分别维护区间中1~26每个数的个数以及一个区间覆盖标记,表示这个区间是否被某一个值覆盖了 在每次排序时,首 ...
- Jmeter3.0 中文乱码的解决方法
在Body Data中输入中文时,发现是乱码,如下图 这种情况在jmeter3.0的版本中才会产生,由于3.0中优化body data后,使用默认的字体(Consolas)不支持汉字的显示. 解决方法 ...
- python 通用装饰器,带有参数的装饰器,
# 使用装饰器对有返回值的函数进行装饰# def func(functionName): # print('---func-1----') # def func_in(): # print(" ...
- Supervisor Linux程序进程管理
Supervisor 介绍 在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.由于在linux中 ...
- Eclipse Memory Analyzer
先写一段可以制造堆溢出的代码 package com.test.jvm.oom; import java.util.ArrayList; import java.util.List; /** * @d ...
- mysql字符集问题汇总
1.设置mysql字符集:在my.ini中添加以下设置,没有my.ini可以将my_default.ini改成他.character-set-server=utf8[client]loose-defa ...
- url、querystring模块获取请求request.url中的不同部分图解
url.parse(string).query | url.parse(string).pathname | | | | | ------ ------------------- http://loc ...
- arcgis 10 File GDB转成9.3 File GDB
背景:已有的File GDB数据是在ArcGIS 10下面创建的,在运行9.3的电脑上无法读取,需要转换成低版本. 方法: 1.在ArcGIS Toolbox中找到相关工具(datamanagemen ...
- 牛客挑战赛30 小G砍树 树形dp
小G砍树 dfs两次, dp出每个点作为最后一个点的方案数. #include<bits/stdc++.h> #define LL long long #define fi first # ...