关于使用vs2019+QT5开放播放pdf功能的分享
最近项目有了开发pdf阅读器的需求,但发现Qt5没有可以开发pdf的API,只能去引入其他库文件帮助实现功能。
具体方法:
在网上搜索大概发现两个通用的方法,一是使用poppler库,里面有直接播放pdf功能的cpp。但下载后发现编译比较困难,没有cmake编译经验的人完全没法下手,网上也找不到已编译的资源,故作罢。(而且网上下载的静态链接库都是.a后缀的Linux库,Windows表示更加懵逼)
于是直接使用mupdf库文件。
使用环境:Win10——VS2019——Qt4.15.2 x86
-
下载mupdf文件地址:https://mupdf.com/downloads/
-
编译mupdf文件搭载环境
下载好后点击platform——win32中的sln进行编译
编译具体过程参考:
VS2015编译MuPDF 1.13.0源码(详细) -
载入mupdf库到vs2019编译器中
将编译好的文件分成include和lib,装进mupdf文件夹中放入工程文件目录下
此次代码功能需包括(libmupdf.lib , libresources.lib ,libthirdparty)三个静态链接文件,如需其他功能请自行添加。
vs2019中打开项目——属性——C/C++ 添加包含目录,将带有头文件的include文件夹加进去
在同一窗口的链接器中点击添加库目录,将带有静态链接库的lib文件加进去
这样就可以在vs2019中引入mupdf中的头文件并使用其功能
- 通过代码实现播放pdf功能
#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=100;
//旋转为0
rotate=0;
//创建上下文
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 < 0 || page_number >= page_count)
{
qDebug()<<stderr<< "page number out of range: "<< page_number + 1<<"page count:"<<page_count;
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()<<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);
*注意 :运行过程中需要注意是32位还是64位,即工程文件和mupdf的位数要匹配,否则报错。
若有编译好的资源可跳过编译,十分方便,当然 需要静态链接资源
有需要指正的地方望不吝赐教。