在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++网上可以搜索很详细 ...
随机推荐
- 基于Web的漏洞利用
1.Nikto 基于Web的漏洞信息扫描 nikto 自动扫描web服务器上没有打补丁的软件,同时同时也检测驻留在服务器上的危险文件,nikto能够识别出特定的问题,检测服务器的配置问题, 检测某台主 ...
- 渗透测试(theharvester >>steghide)
1.不喜欢自己搭建平台来做测试,所以啦..... 网络信息安全漏洞的威胁总结起来就是人的漏洞,拿DNS服务器来说,一般不出现问题就不会管他,所以很多会被黑客利用,DNS服务器保存了企业内部的IP地址列 ...
- bzoj 2190
题意:求 题解:这题...数据范围是真小... 研究一下这一表达式,发现gcd(i,j)=1表示i,j互质,那么互质肯定能想到欧拉函数,可是欧拉函数要求j<i,那么我们变化一下:显然原矩阵是对称 ...
- Python 9*9口诀
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Liuyoushui # Time = 2017/7/18 10:33 print ('\n ...
- 我的第一个Java程序和Java简介
public calss HelloWorld{ public static void main(String[] args){ System.out.println("Hello Worl ...
- error: each element of 'ext_modules' option must be an Extension instance or 2-tuple
在编译cython扩展时出现. 解决办法: 必须先import setup再import extension,否则报错 from setuptools import setup from distut ...
- Java枚举类使用和总结
1.枚举类使用情况一: package com.bie.util; import java.util.HashMap; import java.util.Map; /** * * @author bi ...
- Hadoop的namenode的管理机制,工作机制和datanode的工作原理
HDFS前言: 1) 设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: 2)在大数据系统中作用: 为各类分布式运算框架(如:mapr ...
- linux系统(CentOS7)虚拟机上安装oracle 11g,解决oracle图形界面卡住无法点击next问题
https://www.cnblogs.com/nichoc/p/6416475.html
- ASP.NET CORE Swagger
Package 添加并配置Swagger中间件 将Swagger生成器添加到方法中的服务集合中Startup.ConfigureServices: public void ConfigureServi ...