上一篇讲了基于poppler库的PDF阅读器的开发,这一篇来讲基于mupdf的PDF阅读器的开发。

在上一篇的篇尾我有附效果图,可以很明显的看出来这个效果是非常差的,网络上有童鞋同样遇到了这个问题,并且做了修正,但是,经过测试完全没用(也可能是版本的问题),所以我不得不做新的尝试。

  • 基于mupdf的PDF阅读器

同样的,先要去下载源码,进行解压编译。mupdf库比较好的一点是可以很简单地配置,从而简化很多不需要的库,比如我仅仅是需要提取每一个page,然后放大缩小,上一页、下一页这种操作,而且是在Qt下做的开发,所以很多库就不要了,我的配置如下:

make HAVE_X11=no HAVE_GLUT=no  prefix=./out install

三十秒不到的时间就编译完成了,然后在Qt项目中配置库和头文件就可以进行开发了。在安装目录中有一个例子,可以做参考的,可能因为版本问题,例子没有编过,然而这不是很大的问题,稍作修改就可以了。

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QLabel>
#include <QMouseEvent>
#include <QScrollArea>
#include "mupdf/fitz.h"
#include "mupdf/pdf.h"#include <QPointF>#define Max_abs 20class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();void mouseMoveEvent(QMouseEvent *event);void touchEvent(QTouchEvent *event);void mousePressEvent(QMouseEvent *event);
private:float bestFitScale(int pageW, int pageH);void updatePage();void fz_print_outline(fz_context *ctx, fz_output *out, fz_outline *outline, int level);private:QLabel* label;float scale;int page_number;int page_count;float zoom, rotate;//fz_context *ctx;fz_document *doc;fz_pixmap *pix;QPointF Press_point;public slots:void onPrev();void onNext();void onZoomIn();void onZoomOut();
};#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include <QDebug>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent)
{page_number=0;//第一页为0//100%缩放比zoom=1;//旋转为0rotate=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, "Boost程序库完全开发指南深入C++准标准库.pdf");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;}qDebug() << "page_count: "<< page_count;//get outlinefz_outline *outline = fz_load_outline(ctx, (fz_document*)doc);fz_try(ctx)fz_print_outline(ctx, fz_stderr(ctx), outline, 0);fz_always(ctx)fz_drop_outline(ctx, outline);fz_catch(ctx)fz_rethrow(ctx);QScrollArea *LogoArea = new QScrollArea(this);//LogoArea->setGeometry(0, 0, width(), height());LogoArea->setGeometry(0, 0, 1024, 600);LogoArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);LogoArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);//QWidget *w = new QWidget(LogoArea);//LogoArea->setWidget(w);//QScrollBar* vertScrollBar = LogoArea->verticalScrollBar();label=new QLabel(this);label->setVisible(false);LogoArea->setWidget(label);LogoArea->setAlignment(Qt::AlignCenter);QPushButton* prevBtn = new QPushButton(this);prevBtn->setText("Prev");prevBtn->setGeometry(910, 240, 60,100);connect(prevBtn, SIGNAL(pressed()), this, SLOT(onPrev()));QPushButton* nextBtn = new QPushButton(this);nextBtn->setText("Next");nextBtn->setGeometry(910, 340, 60,100);connect( nextBtn, SIGNAL(pressed()), this, SLOT(onNext()));QPushButton* plusBtn = new QPushButton(this);plusBtn->setText("+");plusBtn->setGeometry(910, 50, 20, 20);connect( plusBtn, SIGNAL(pressed()), this, SLOT(onZoomIn()));QPushButton* minBtn = new QPushButton(this);minBtn->setText("-");minBtn->setGeometry(940, 50, 20, 20);connect( minBtn, SIGNAL(pressed()), this, SLOT(onZoomOut()));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;}//计算缩放以及旋转updatePage();
}Widget::~Widget()
{}void Widget::mouseMoveEvent(QMouseEvent *event)
{qDebug() << event;int xMove;int yMove;xMove = Press_point.x() - event->localPos().x();yMove = Press_point.y() - event->localPos().y();event->accept();
}void Widget::mousePressEvent(QMouseEvent *event)
{Press_point = event->localPos();
}void Widget::touchEvent(QTouchEvent *event)
{qDebug() << event;
}float Widget::bestFitScale(int pageW, int pageH)
{return ((width() / pageW) > (height() / pageH) ? (height() / pageH) : (width() / pageW));
}void Widget::updatePage()
{fz_matrix ctm = fz_scale( zoom, zoom);fz_pre_rotate(ctm, rotate);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 = pix->samples;int width = fz_pixmap_width(ctx, pix);int height = fz_pixmap_height(ctx, pix);qDebug() << "width: "<<width;qDebug() << "height: "<<height;label->setGeometry(0,0,width,height);label->setAlignment(Qt::AlignCenter);QImage image(samples, width, height,pix->stride,QImage::Format_RGB888);label->setPixmap(QPixmap::fromImage(image));label->setVisible(true);fz_drop_pixmap(ctx, pix);update();
}void Widget::onPrev()
{qDebug() << "onPrev";page_number--;if(page_number <= 0)page_number = 0;updatePage();
}void Widget::onNext()
{qDebug() << "onNext";page_number++;if(page_number >= page_count -1)page_number = page_count -1;updatePage();
}void Widget::onZoomIn()
{zoom += 0.05;updatePage();
}void Widget::onZoomOut()
{zoom -= 0.05;updatePage();
}//Tools
void Widget::fz_print_outline(fz_context *ctx, fz_output *out, fz_outline *outline, int level)
{int i;if(outline == NULL)qDebug()<< "outline is NULL!";while (outline){for (i = 0; i < level; i++)//    fz_write_printf(ctx, out, "\t");//fz_write_printf(ctx, out, "%s\t%s\n", outline->title, outline->uri);qDebug()<< outline->title<<" " << outline->uri;if (outline->down)fz_print_outline(ctx, out, outline->down, level + 1);outline = outline->next;}
}

效果图

这个显示的效果是相当令人满意的。之前有网友说poppler不能满足性能,确实如此。

基于mupdf的PDF阅读器相关推荐

  1. 基于pyQt5的pdf阅读器

    主要基于import fitz模块 一定是操作pip install PyMuPDF不是安装fitz 主要代码: def generatePDFView(self):self.doc = fitz.o ...

  2. iOS 中使用Mupdf教程 pdf阅读器

    转载注明出处:http://blog.csdn.net/hongqifeiwu/article/details/46009095 浩宇提供:若有疑问可以相互探讨,邮箱1223556769@qq.com ...

  3. android 使用mupdf,如何在android上嵌入mupdf作为pdf阅读器

    android 阅读器 调研pdf阅读器效果对比阅读器:有道词典网易云阅读多看阅读iReader智器阅读PDF专业阅读器Foxit PDFFBreader android 阅读器 调研 pdf阅读器效 ...

  4. QT开发的pdf阅读器资料

    详细说明:基于QT的一款建议pdf阅读器,可以进行移植,可以再pc上运行.-Recommendations based on QT' s a pdf reader, can be transplant ...

  5. 基于MuPDF和Qt的PDF阅读器的开发

    基于MuPDF和Qt的PDF阅读器的开发 一.引言 设备上要渲染显示PDF文档,类似Adobe Reader.福昕阅读器等软件.如何去实现?Handling PDF这篇文档讨论介绍了在Qt应用程序中各 ...

  6. 基于qt与mupdf库的pdf阅读器开发

    pdf阅读器 下载mupdf源码 编译mupdf源码 qt工程链接mupdf源码静态库 参照 mupdf/docs/examples/example.c 开发 mainwindows.ui mainw ...

  7. chrome pdf android,Android PDF阅读器 (基于谷歌平台的Adobe Reader)

    Android PDF阅读器 (基于谷歌平台的Adobe Reader):Adobe Reader 是用于打开和使用在 Adobe Acrobat 中创建的 Adobe PDF 的工具. 虽然无法在 ...

  8. 免费PDF阅读器有哪些? 14款强烈推荐的PDF阅读器!

    即使经过这么多年,PDF 仍然是最受欢迎的阅读格式之一.从阅读电子书或填写在线表格到创建用户手册,PF 格式仍然是最受欢迎的阅读方式.虽然现在的网络浏览器已经配备了基本的 PDF 阅读功能,但您仍然需 ...

  9. 打造全键盘操作的PDF阅读器

    其实我只想要一个非常简单的PDF阅读器,不要很花哨的功能,只要能够: 速度够快,不要翻一页等半天: 全键盘操作,不想在鼠标和键盘之间来回倒腾: 可以改变背景色,深夜的白光好刺眼: 自由旋转页面,有些P ...

  10. android pdf阅读器开发_如何在 Windows 10 中将 Firefox 设置为默认 PDF 阅读器

    PDF 作为办公一族中的必备文档,很多人都会编辑或者创建 PDF 文档,而在 Windows 系统中并没有默认的 PDF 阅读器.而在新版的 Microsoft Edge微软已在开始提供有真正的高级 ...

最新文章

  1. Linux shell 学习笔记(10)— 处理用户输入(命令行读取参数、读取用户输入、超时处理)
  2. oracle最大实例数,【Oracle】RAC的多实例数据迁移至单机的多实例。
  3. Ubuntu16.04安装NVIDIA驱动+CUDA9.0+cuDNN7.0
  4. socket 编程入门教程(三)TCP原理:7、TCP连接的关闭
  5. linux命令:vim
  6. docker -v 覆盖了容器中的文件_10分钟让你理解 docker 容器中的 uid 和 gid
  7. php测试号推送消息失败,信息发送失败是什么原因
  8. 如何用sbt新建akka项目
  9. Team Foundation Server 2010 安装、部署与配置(五):用户权限管理 .
  10. java线程池_Java 并发编程 线程池源码实战
  11. CALLBACKS IN C++ USING TEMPLATE FUNCTORS
  12. PAIP.java程序调试的注意点及流程总结
  13. c语言for循环延时函数作用,C语言循环语句实现单片机延时函数.pdf
  14. 220kv变电站计算机监控系统网络结构图,变电站二次系统设计计算机监控系统组屏(柜)方案...
  15. ac1900修改代理服务器,tplink ac1900路由器怎么设置?
  16. 计算机体系结构实验三 指令调度和延迟分支
  17. 人脸脸部识别技术_面部识别技术的道德安全问题
  18. formate在python_python的format方法
  19. CentOS7安装 jq
  20. 华为服务器图片无法显示,服务器的图片无法显示

热门文章

  1. 珠宝行业电子秤串口程序开发
  2. 关于spark错误 [Could not locate executable null\bin\winutils.exe in the Hadoop binaries】解决方法
  3. 外贸公司比较常用邮箱有哪几个?邮箱的区别是什么?
  4. 4/6 深搜、广搜专题+二分答案+单调队列
  5. 如何用计算机校验信息,支付宝短信校验服务怎么开通?-电脑教程
  6. RHEL6: Server panicked in 'redirfs' module
  7. CGB2202API基础第1天
  8. 爆红十年后,谁“切”了苹果?
  9. 华为HCNA独家视频课程
  10. DirectX和OPenGL 与 UE4、U3D、Webgl(ThreeJS)的关系