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+vs2015html
下载Mupdf库
https://mupdf.com/downloads/git
编译Mupdf
在mupdf-1.12.0-source\platform\win32目录下就有现成的mupdf.sln。github
这里须要注意:这个工程默认使用的是/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.htmlwindows
工程里默认生成的是都是静态库,请注意!api
根据测试须要的分别是libmupdf.lib、libresources.lib、libthirdparty.lib这三个库(只使用了docs\examples\example.c的代码,使用别的函数可能须要再编译别的工程)
分别修改解决方案中的libmupdf、libthirdparty、libresources这三个工程,将debug下改为/MDd,release下改为/MD,编译便可获得这3个文件。其中libresources只有release版本的,因此debug模式下,我也引用这个文件。ide
固然你嫌麻烦或者仍是不知道该怎么编译,能够去个人github直接下载编译好的静态库。函数
在Qt工程中引入Mupdf静态库
引入lib文件
新建一个工程,在工程的图标上右键——添加库——外部库。平台只勾选windows,连接选择静态,以后选择对应的库就能够了。(本人将debug与release编译的分别放在debug与release文件夹中)
添加包含目录
将Mupdf目录中的include复制到工程目录下(本人又新建了一个mupdf,将全部文件都放在里面了)
本人是这么写的,具体能够参考源代码:
INCLUDEPATH += $$PWD/mupdf/include/
以后运行QMake。测试
编写代码进行测试
代码是根据Mupdf中的案例文件example.c中的代码改写ui
#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(newUi::Widget)
{
ui->setupUi(this);char *input = const_cast< char* >("document.pdf");floatzoom, rotate;intpage_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()<
}//注册文档控制
fz_try(ctx)
fz_register_document_handlers(ctx);
fz_catch(ctx)
{
qDebug()<
fz_drop_context(ctx);return;
}//打开文档
fz_try(ctx)
doc=fz_open_document(ctx, input);
fz_catch(ctx)
{
qDebug()<
fz_drop_context(ctx);return;
}//取得总的页数
fz_try(ctx)
page_count=fz_count_pages(ctx, doc);
fz_catch(ctx)
{
qDebug()<
fz_drop_document(ctx, doc);
fz_drop_context(ctx);return;
}if (page_number < 0 || page_number >=page_count)
{
qDebug()<
fz_drop_document(ctx, doc);
fz_drop_context(ctx);return;
}//计算缩放以及旋转
fz_scale(&ctm, zoom / 100, zoom / 100);
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), 0);
fz_catch(ctx)
{
qDebug()<
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=newQLabel; 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() {deleteui; }
参考代码
https://github.com/blueroseslol/QtMupdfthis
找到一个以前有人封装的库,不过通过测试是没法成功编译的,不过能够参考一下mupdf库的用法。
https://github.com/xiangxw/mupdf-qt
别的参考:
http://blog.csdn.net/chenyijun/article/details/42582977