Qt + mupdf 显示PDF,支持翻页

使用Qt + mupdf 实现PDF阅读器,支持翻页(上一页、下一页)

 

思路:

PDF阅读器:使用mupdf,将PDF文件拆分成单个page页,将page页转为QImage图像,使用QListWidget来装载所有的QImage,这样Qt就可以显示出所有图像(完整的PDF)。

翻页:根据滚动条,确认当前是哪一页,然后实现【上一页、下一页】功能

 

代码:

// pro文件设置
INCLUDEPATH += mupdf
LIBS += -L$$PWD/lib -llibextract -llibmupdf -llibmuthreads -llibthirdparty

QMAKE_CFLAGS_DEBUG += -MTd
QMAKE_CXXFLAGS_DEBUG += -MTd

 

// 显示PDF文件--PDF阅读器
#include <QListWidget>
#include <QListWidgetItem>
#include <QImage>
#include <QIcon>
#include <QSize>
#include "pdf.h"
#include "fitz.h"


// 对控件  QListWidget 属性进行设置
/**
*    1. 使用Qt Create编写的demo,所以 QListWidget 控件是直接在ui文件拉进入的
*    2. 需要对每个 QListWidgetItem 加10px的间隔,不然翻页计算不准,或者是 px_num+1 也行
*/
ui->listWidget->setViewMode(QListView::IconMode);
ui->listWidget->setIconSize(QSize(1050, 1485));        
ui->listWidget->setSpacing(10);  
ui->listWidget->setResizeMode(QListView::Adjust);
ui->listWidget->setMovement(QListView::Static);


// 显示 PDF
fz_context* ctx =  fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
fz_register_document_handlers(ctx);    // *:这里报错,就需要设置 MTD 或者 MDD
fz_document* doc =  fz_open_document(ctx, "F:\\1.pdf");

int pageCount = fz_count_pages(ctx, doc);

float zoom = (float)300 / (float)72;
fz_matrix ctm = fz_scale(zoom, zoom);

for(int i=0; i<pageCount; i++)
{
    fz_pixmap* pix = fz_new_pixmap_from_page_number(ctx, doc, i, ctm, fz_device_rgb(ctx), 0);

    float b = (float)pix->w / (float)1050;
    int t_h = pix->h / b;
    QSize t_size(1050, t_h);

    QImage img(pix->samples, pix->w, pix->h, pix->stride, QImage::Format_RGB888);
    img = img.scaled(1050, t_h);
    
    QListWidgetItem *tempImageItem = new QListWidgetItem;
    tempImageItem->setIcon(QIcon(QPixmap::fromImage(img)));
    tempImageItem->setSizeHint(t_size);
    ui->listWidget->addItem(tempImageItem);

    fz_drop_pixmap(ctx, pix);
}

fz_drop_document(ctx, doc);
fz_drop_context(ctx);

 

// 获取当前是哪一页
int getShowPageIndex()
{
    // image_height 是 1485,在最开始设置 QListWidget 时就有用到
    int px_num = ui->listWidget->verticalScrollBar()->value();
    double page_num = ceil(px_num / image_height);
    return page_num;
}

// 上一页
int page_num = getShowPageIndex();
if(page_num > 0)
    ui->listWidget->setCurrentRow(page_num-1, QItemSelectionModel::Current);

// 下一页
int page_num = getShowPageIndex();
int page_count = ui->listWidget->count();

if(page_num < page_count-1)
    ui->listWidget->setCurrentRow(page_num+1, QItemSelectionModel::Current);

 

 

 

代码比较简单,但是研究mupdf这个库还是花了点时间的,实属不易

另:公司使用的时候,可能还需要讲签名图片贴到PDF上,请参考另一篇文章:mupdf实用操作

 

posted @ 2023-09-18 16:18  十一的杂文录  阅读(535)  评论(0编辑  收藏  举报