QT笔记-PDF阅读器(附带完整源码)- 导入PDF文件,在窗体上显示,并提取PDF的文字内容

2023-11-12

环境搭建:
1、mupdf-1.17.0-source库。mupdf-1.17.0-source默认是VS2019的工程,由于示例用的是VS2017,所以需要用VS2017重新编译mupdf-1.17.0-source工程,生成LIB库文件。
2、vs2017+QT5.14.2

3、mupdf-1.17.0-source库的位置  https://download.csdn.net/download/C_panpan/88157816https://download.csdn.net/download/C_panpan/88157816

 示例代码:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_pdfDemo.h"

class pdfDemo : public QMainWindow
{
    Q_OBJECT

public:
    pdfDemo(QWidget *parent = nullptr);
    ~pdfDemo();
	bool PDF2PNG(std::string pdfFilePath, int pdfPageIdx, std::string outputPNGFilePath);
	bool loadTxt(std::string pdfFilePath, int pdfPageIdx, std::string outputPNGFilePath);
private slots:
	void OnNextPage();
private:
    Ui::pdfDemoClass ui;

	int m_ipage;
};
#include "pdfDemo.h"
#include "mupdf/fitz.h"
#include "mupdf/pdf.h"
#include <QLabel>


bool pdfDemo::PDF2PNG(std::string pdfFilePath, int pdfPageIdx, std::string outputPNGFilePath)
{
	if (pdfFilePath.empty() || pdfPageIdx < 0)
	{
		return false;
	}

	//使用默认值
	int pageCount = 0;
	float zoom = 100;
	float rotate = 0;

	fz_context *ctx;
	fz_document *doc;
	fz_pixmap *pix;
	fz_matrix ctm;
	fz_stext_page *text;
	int x, y;

	/* Create a context to hold the exception stack and various caches. */
	ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
	if (!ctx)
	{
		fprintf(stderr, "cannot create mupdf context\n");
		return false;
	}

	/* Register the default file types to handle. */
	fz_try(ctx)
	{
		fz_register_document_handlers(ctx);
	}
	fz_catch(ctx)
	{
		fprintf(stderr, "cannot register document handlers: %s\n", fz_caught_message(ctx));
		fz_drop_context(ctx);
		return false;
	}

	/* Open the document. */
	fz_try(ctx)
	{
		doc = fz_open_document(ctx, pdfFilePath.c_str());
	}
	fz_catch(ctx)
	{
		fprintf(stderr, "cannot open document: %s\n", fz_caught_message(ctx));
		fz_drop_context(ctx);
		return false;
	}

	/* Count the number of pages. */
	fz_try(ctx)
	{
		pageCount = fz_count_pages(ctx, doc);
	}
	fz_catch(ctx)
	{
		fprintf(stderr, "cannot count number of pages: %s\n", fz_caught_message(ctx));
		fz_drop_document(ctx, doc);
		fz_drop_context(ctx);
		return false;
	}

	if (pdfPageIdx < 0 || pdfPageIdx >= pageCount)
	{
		fprintf(stderr, "page number out of range: %d (page count %d)\n", pdfPageIdx + 1, pageCount);
		fz_drop_document(ctx, doc);
		fz_drop_context(ctx);
		return false;
	}

	/* Compute a transformation matrix for the zoom and rotation desired. */
	/* The default resolution without scaling is 72 dpi. */
	ctm = fz_scale(zoom / 100, zoom / 100);
	ctm = fz_pre_rotate(ctm, rotate);

	/* Render page to an RGB pixmap. */
	fz_buffer *bu;
	fz_try(ctx)
	{
		pix = fz_new_pixmap_from_page_number(ctx, doc, pdfPageIdx, ctm, fz_device_rgb(ctx), 0);

		//提取PDF中的文字
		fz_page *page = pdf_load_page_imp(ctx, doc, 0, pdfPageIdx);
		const fz_stext_options opts = { FZ_STEXT_PRESERVE_IMAGES };
		text = fz_new_stext_page_from_page(ctx, page, &opts);
		bu = fz_new_buffer_from_stext_page(ctx, text);

        //中文乱码
		QString str = QString::fromLocal8Bit(reinterpret_cast<const char*>(bu->data));

        //中文不会乱码
		std::string str1 = (char*)bu->data;
		QString sstr = QString::fromStdString(str1);

		ui.label_2->setText(sstr);
	}
	fz_catch(ctx)
	{
		fprintf(stderr, "cannot render page: %s\n", fz_caught_message(ctx));
		fz_drop_document(ctx, doc);
		fz_drop_context(ctx);
		return false;
	}

	fz_try(ctx)
	{
		//保存为PNG图片
		fz_save_pixmap_as_png(ctx, pix, outputPNGFilePath.c_str());

		//渲染成图片
//   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;
		ui.label->setPixmap(QPixmap::fromImage(image)); 
		//ui.stackedWidget->addWidget(label);
		//ui.stackedWidget->setCurrentIndex(0);
	}
	fz_catch(ctx)
	{
		fz_drop_document(ctx, doc);
		fz_drop_context(ctx);
		return false;
	}

	/* Clean up. */
	fz_drop_pixmap(ctx, pix);
	fz_drop_document(ctx, doc);
	fz_drop_context(ctx);

	return true;
}

bool pdfDemo::loadTxt(std::string pdfFilePath, int pdfPageIdx, std::string outputPNGFilePath)
{
	return false;
}

pdfDemo::pdfDemo(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

	connect(ui.btnNext, SIGNAL(clicked()), this, SLOT(OnNextPage()));
	m_ipage = 0;
	OnNextPage();
}

pdfDemo::~pdfDemo()
{}

void pdfDemo::OnNextPage()
{
	std::string pdfFilePath = "1.pdf";
	std::string outputFilePath = "a.png";
	bool isOk = PDF2PNG(pdfFilePath, m_ipage, outputFilePath);
	m_ipage++;
}

 运行效果

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT笔记-PDF阅读器(附带完整源码)- 导入PDF文件,在窗体上显示,并提取PDF的文字内容 的相关文章

随机推荐