```c++
#include "pdfbrowser.h"
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QDebug>
PDFBrowser::PDFBrowser(QWidget *parent)
: QWidget{parent}
{
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_StaticContents);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
vScrollBar = new QScrollBar(Qt::Vertical, this);
hScrollBar = new QScrollBar(Qt::Horizontal, this);
vScrollBar->setVisible(true);
hScrollBar->setVisible(true);
m_scrollArea = new QScrollArea(this);
m_scrollArea->setBackgroundRole(QPalette::Base);
m_scrollArea->setAlignment(Qt::AlignCenter);
m_scrollArea->setFrameShape(QFrame::NoFrame);
m_scrollArea->setVerticalScrollBar(vScrollBar);
m_scrollArea->setHorizontalScrollBar(hScrollBar);
m_scrollArea->setWidgetResizable(true);
m_scrollAreaContentLayout = new QVBoxLayout;
scrollAreaContent = new QWidget;
scrollAreaContent->setLayout(m_scrollAreaContentLayout);
m_scrollArea->setWidget(scrollAreaContent);
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget(m_scrollArea);
label = new QLabel(this);
m_scrollAreaContentLayout->addWidget(label);
setLayout(layout);
connect(vScrollBar, &QScrollBar::valueChanged, this, &PDFBrowser::onScrollBarValueChanged);
connect(hScrollBar, &QScrollBar::valueChanged, this, &PDFBrowser::onScrollBarValueChanged);
document = nullptr;
qDebug()<<"到这里了";
}
PDFBrowser::~PDFBrowser(){
if(m_scrollArea!=nullptr)
delete m_scrollArea;
if(vScrollBar!=nullptr)
delete vScrollBar;
if(hScrollBar!=nullptr)
delete hScrollBar;
if(document!=nullptr)
delete document;
FPDF_DestroyLibrary();
}
void PDFBrowser::resizeEvent(QResizeEvent *event){
this->m_scrollArea->resize(this->size());
//在widget重新变更位置时改变scrollbar
qDebug()<<"m_scrollArea->height():"+QString::number(m_scrollArea->height());
qDebug()<<"m_scrollArea->width():"+QString::number(m_scrollArea->width());
qDebug()<<"PDFBrowser->width():"+QString::number(this->width());
qDebug()<<"PDFBrowser->height():"+QString::number(this->height());
int totalHeight = document->getTotalHeightInPixel();
int maxWidth = document->getMaxWidthInPixel();
int vq = totalHeight - m_scrollArea->height();
int hq = maxWidth - m_scrollArea->width();
qDebug()<<"vq:"+QString::number(vq);
qDebug()<<"hq:"+QString::number(hq);
qDebug()<<"maxWidth:"+QString::number(maxWidth);
qDebug()<<"totalHeight:"+QString::number(totalHeight);
vScrollBar->setRange(0, totalHeight - m_scrollArea->height());
hScrollBar->setRange(0, maxWidth - m_scrollArea->width());
vScrollBar->setSingleStep(20);
vScrollBar->setPageStep(20);
hScrollBar->setSingleStep(20);
hScrollBar->setPageStep(20);
vScrollBar->setVisible(true);
hScrollBar->setVisible(true);
QWidget::resizeEvent(event);
redraw();
qDebug()<<" resizeEvent vScrollBar:"+QString::number(vScrollBar->maximum());
qDebug()<<" resizeEvent m_scrollArea:"+QString::number(m_scrollArea->height());
}
PDFDocument* PDFBrowser::loadPDF(const QString& fileName){
qDebug()<<"hi hi hi555";
FPDF_InitLibrary();
FPDF_DOCUMENT pdocument = FPDF_LoadDocument(fileName.toStdString().c_str(), nullptr);
qDebug()<<"hi hi hi556";
if (pdocument) {
PDFDocument* document = new PDFDocument(pdocument);
qDebug()<<"hi hi hi551";
document->loadAllPage();
this->document = document;
int totalHeight = document->getTotalHeightInPixel();
int maxWidth = document->getMaxWidthInPixel();
m_scrollArea->setMaximumWidth(maxWidth - m_scrollArea->width());
m_scrollArea->setMaximumHeight(totalHeight - m_scrollArea->height());
vScrollBar->setRange(0, totalHeight - m_scrollArea->height());
hScrollBar->setRange(0, maxWidth - m_scrollArea->width());
};
redraw();
qDebug()<<" load vScrollBar:"+QString::number(vScrollBar->maximum());
qDebug()<<" load m_scrollArea:"+QString::number(m_scrollArea->height());
return this->document;
}
void PDFBrowser::redraw(){
int totalHeight = document->getTotalHeightInPixel();
int maxWidth = document->getMaxWidthInPixel();
// m_scrollArea->setMaximumWidth(maxWidth - m_scrollArea->width());
// m_scrollArea->setMaximumHeight(totalHeight - m_scrollArea->height());
qDebug()<<"vScrollBar:"+QString::number(vScrollBar->maximum());
qDebug()<<"m_scrollArea:"+QString::number(m_scrollArea->height());
if (document == nullptr) {
return;
}
QPixmap result(m_scrollArea->width(), m_scrollArea->height());
QPainter painter(&result);
// 设置背景颜色
painter.setBackground(Qt::darkGray);
painter.setBrush(Qt::darkGray);
// 获取widget大小
int canvasWidth = m_scrollArea->width();
int canvasHeight = m_scrollArea->height();
// 填充矩形区域
painter.drawRect(0, 0, canvasWidth, canvasHeight);
painter.fillRect(0, 0, canvasWidth, canvasHeight, Qt::white);
// Get scrollbar position
int selection = vScrollBar->value();
int hSelection = hScrollBar->value();
qDebug()<<"selection:"+QString::number(selection);
qDebug()<<"hSelection:"+QString::number(hSelection);
// Get canvas size and calculate beginX
QSize canvasSize = m_scrollArea->size();
//居中
int beginX = 0;
if (canvasSize.width() > document->getMaxWidthInPixel()) {
beginX = (canvasSize.width() - document->getMaxWidthInPixel()) / 2;
}
// Draw PDF pages to QPixmap and show it on canvas
QGraphicsScene scene;
QList<QGraphicsPixmapItem*> items;
int pageAtY = selection;
PDFPage *page = document->getPageAtPixel(pageAtY);
//获取当前页是第几页
int index = page->getIndex();
//前几页的总长度
int temp = 0;
for(int i=0;i<index;i++){
temp+=document->getAllPage()[i].getPageSizeInPixel(document->getFPdf_DOCUMENT())[1];
}
painter.setBrush(QColor(Qt::white));
// 绘制矩形并填充背景色
int x = -hSelection + beginX;
int y = 0;
int width = document->getMaxWidthInPixel();
int height = canvasHeight;
painter.drawRect(x, y, width, height);
painter.fillRect(x, y, width, height, painter.brush());
// 当前页应该在这个位置绘制
int maginY = temp - selection;
int paintedCount = 0;
int drawY = maginY;
PDFPage *currentPage = nullptr;
while (paintedCount <=canvasHeight) {
qDebug()<<"drawY:"+QString::number(drawY);
if(page==nullptr)
return;
if (currentPage == page) {
break;
}
currentPage = page;
int pageWidth = currentPage->getPageSizeInPixel(this->document->getFPdf_DOCUMENT())[0];
int pageHeight = currentPage->getPageSizeInPixel(this->document->getFPdf_DOCUMENT())[1];
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(currentPage->render(-hSelection + beginX, drawY, pageWidth, pageHeight, 0, 0));
item->setPos(-hSelection + beginX, drawY);
items.append(item);
pageAtY += currentPage->getPageSizeInPixel(this->document->getFPdf_DOCUMENT())[1];
page = document->getPageAtPixel(pageAtY);
// 已经绘制了这么多,离整个clientArea还有一段距离,不够的话接着取下一页
paintedCount += pageHeight + maginY;
// 下一页的坐标(滚动条偏移+当前页大小+偏移),多一个像素去寻找下一页
pageAtY = pageHeight + selection + maginY + 1;
// 下一页画的y坐标
drawY += pageHeight;
}
// int px = -hSelection + beginX;
// int py = maginY;
// 在绘图设备上绘制所有QPixmap
// foreach (const QPixmap& pixmap, list) {
// painter.drawPixmap(px, py, pixmap);
// int x1 = px;
//int y1 = pixmap.height() + py + 1;
//int x2 = pixmap.width() + px;
//int y2 = y1;
//painter.drawLine(x1, y1, x2, y2);
//py += pixmap.height() + 1; // 两个QPixmap之间加上10px的间距
//}
foreach(QGraphicsPixmapItem* item, items) {
scene.addItem(item);
}
// 在绘图设备上绘制所有QGraphicsPixmapItem
scene.render(&painter);
label->setPixmap(result);
painter.end();
}
#include <QApplication>
#include <QWidget>
#include <QScreen>
class CenteredWidget : public QWidget {
public:
CenteredWidget(QWidget* parent = nullptr)
: QWidget(parent) {
setFixedSize(870, 770);
const QRect screenRect = QGuiApplication::primaryScreen()->availableGeometry();
move((screenRect.width() - width()) / 2,
(screenRect.height() - height()) / 2);
}
};
#include <QImage>
#include "fpdfview.h"
#include "fpdf_save.h"
// 渲染 PDF 页面到 QImage 中
QImage renderPageToQImage(FPDF_PAGE page, int dpi)
{
// 计算需要的图像大小(以像素为单位)
int width = FPDF_GetPageWidth(page) * dpi / 72.0;
int height = FPDF_GetPageHeight(page) * dpi / 72.0;
// 创建内存设备并将渲染结果保存到其中
QImage image(width, height, QImage::Format_RGBA8888);
FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(width, height, FPDFBitmap_BGR, image.bits(), (int)image.bytesPerLine());
FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, FPDF_ANNOT);
// 销毁位图对象
FPDFBitmap_Destroy(bitmap);
return image;
}
QImage pdfToQImage(const QString& filePath, int pageIndex, int dpi);
QImage renderPageToQImage(FPDF_PAGE page, int dpi);
// 将 PDF 文件转换为 QImage
QImage pdfToQImage(const QString& filePath, int pageIndex, int dpi)
{
// 打开 PDF 文件
QByteArray byteArray = filePath.toUtf8();
const char* fileName = byteArray.constData();
FPDF_DOCUMENT document = FPDF_LoadDocument(fileName, nullptr);
if (!document) {
qDebug() << "Failed to load document.";
return QImage();
}
// 获取页面数量并打开指定页码的页面
int pageCount = FPDF_GetPageCount(document);
if (pageIndex >= pageCount) {
qDebug() << "Invalid page index.";
FPDF_CloseDocument(document);
return QImage();
}
FPDF_PAGE page = FPDF_LoadPage(document, pageIndex);
if (!page) {
qDebug() << "Failed to load page.";
FPDF_CloseDocument(document);
return QImage();
}
// 设置 DPI 并渲染页面到 QImage 中
QImage image = renderPageToQImage(page, dpi);
// 关闭页面并销毁文档对象
FPDF_ClosePage(page);
FPDF_CloseDocument(document);
return image;
}
#include <QApplication>
#include <QApplication>
#include <QFileDialog>
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QDebug>
#include <QPushButton>
#include "pdfbrowser.h"
// Include PDFium headers
#include "fpdfview.h"
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
CenteredWidget window;
window.setWindowTitle("PDF Browser");
PDFBrowser* pdfBrowser = new PDFBrowser(&window);
pdfBrowser->resize(window.size());
// pdfBrowser->loadPDF("D:\\pdfD\\040300122068.pdf");
pdfBrowser->loadPDF("D:\\pdfD\\2.pdf");
pdfBrowser->setFixedSize(window.size());
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget(pdfBrowser);
qDebug()<<"window的长:"+QString::number(window.height());
qDebug()<<"window的款:"+QString::number(window.width());
window.setLayout(layout);
window.show();;
return a.exec();
}
```