mupdf
cpp
#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; }
pdfium
cpp
#include "src/pdfium_aux.h"
#include <iostream>
#include <filesystem>
int main(int argc, char* argv[])
{
try {
RenderPdfOptions options(argc, argv);
if (options.invalid()) {
std::cout << "usage:\nrender_pdf.exe inputfile.pdf [output_file.png]" << std::endl;
return -1;
}
InitPdfium(options);
ScopedFPDFDocument doc(FPDF_LoadDocument(options.inputFile().c_str(), options.password().c_str()));
std::cout << "rendering " << std::filesystem::path(options.inputFile()).filename() << "...\n";
auto[from_page_index, to_page_index] = options.range().get(doc.get());
int num_pages = to_page_index - from_page_index + 1;
for (auto index = from_page_index; index <= to_page_index; index++) {
ScopedFPDFPage page(FPDF_LoadPage(doc.get(), index));
auto bitmap = RenderPage(page.get(), options.scale());
auto out_filename = options.outputFile( (num_pages > 1) ? std::optional<int>(index) : std::nullopt);
WriteImage( bitmap.get(), options.imageFormat(), out_filename );
std::cout << " generated " << std::filesystem::path(out_filename).filename() << ".\n";
}
std::cout << "complete.\n";
} catch (std::runtime_error e) {
std::cout << "error: " << e.what() << std::endl;
return -1;
} catch (...) {
std::cout << "error: unkown fatal error occurred" << std::endl;
return -1;
}
return 0;
}
popper
cpp
#include "widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent),
Cur_Page(0)
{
int numPages = 0;
scale = 1;
document = poppler::document::load_from_file("a.pdf");
Total_page = document->pages();
qDebug() << "PDF pages: " << numPages;
label = new QLabel(this);
label->setGeometry(0,0,1024,600);
label->setAlignment(Qt::AlignCenter);
//label->setPixmap(QPixmap::fromImage(qimage));
label->setVisible(true);
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()));
updatePage();
}
Widget::~Widget()
{
}
void Widget::resizeEvent(QResizeEvent *event)
{
this->setGeometry(0,0,1024,600);
}
void Widget::updatePage()
{
poppler::page_renderer* render = new poppler::page_renderer();
//render->set_render_hint(poppler::page_renderer::render_hint::antialiasing);
//render->set_render_hint(poppler::page_renderer::render_hint::text_antialiasing);
render->set_render_hints(poppler::page_renderer::render_hint::antialiasing |
poppler::page_renderer::render_hint::text_antialiasing
);
poppler::page* page = document->create_page(Cur_Page);
poppler::image image = render->render_page(page, 72, 72, -1,-1,-1, -1);
qDebug() << "image format: " << image.format();
int width = render->render_page(page).width();
int height = render->render_page(page).height();
qDebug() << "width: " << width;
qDebug() << "height: " << height;
qDebug()<< "scale: "<< scale * 100 << "\%";
QImage qimage((uchar*)image.data(), width, height, QImage::Format::Format_ARGB32);
qDebug() << "image format: "<<qimage.format();
label->setPixmap(QPixmap::fromImage(qimage.scaledToWidth(width*scale)));
}
void Widget::onPrev()
{
if(Cur_Page == 0)
Cur_Page = 0;
else
Cur_Page--;
//load page
updatePage();
}
void Widget::onNext()
{
if(Cur_Page == Total_page -1)
Cur_Page = Total_page -1;
else
Cur_Page++;
//load page
updatePage();
}
void Widget::onZoomIn()
{
scale += 0.15;
updatePage();
}
void Widget::onZoomOut()
{
scale -= 0.15;
updatePage();
}
xpdf
参考
GitHub - xiangxw/mupdf-qt: Qt5 interface of the popular PDF library MuPDF
GitHub - ylzf0000/Mini-Pdf-Reader: 一个简单的PDF阅读器,利用Qt + Mupdf
https://gitee.com/liupeng2018my/mupdf
GitHub - coolwanglu/pdf2htmlEX: Convert PDF to HTML without losing text or format.
GitHub - paulovap/qtpdfium: Pdf Redening on Qt
http://code.qt.io/qt-labs/qtpdf.git
PDFCreator - Browse /PDFCreator at SourceForge.net
https://github.com/dannyedel/dspdfviewer
https://github.com/CryFeiFei/pdfdemo
Poppler Win32 download | SourceForge.net
GitHub - CryFeiFei/Reader: Reader for PDF,use Qt5 and Poppler
https://github.com/flexpaper/pdf2image
https://github.com/flexpaper/pdf2json
GitHub - Archie3d/qpdf: PDF viewer widget for Qt