应用场景
1. 档案管理
在企业或机构的档案管理中,常常会有大量的 pdf 格式的文件,如合同、报告、发票等。这些文件的原始文件名可能没有明确的标识,不利于查找和管理。通过批量获取 pdf 局部文字内容并改名,可以根据文件中的关键信息(如合同编号、报告标题等)为文件重新命名,提高档案管理的效率。
2. 学术资料整理
在学术研究中,会收集大量的学术论文、研究报告等 pdf 文件。这些文件的文件名可能是随机生成的或者不具有明确的主题信息。使用本方案可以提取 pdf 中的标题、作者等关键信息,为文件重新命名,方便学者对学术资料进行分类和检索。
实现方案概述
本方案将使用 qt 构建图形用户界面,结合百度云 ocr api 实现批量获取 pdf 局部文字内容并对文件进行改名的功能。主要步骤包括:使用 qt 选择 pdf 文件目录,将 pdf 转换为图片(因为百度云 ocr 主要处理图片),指定局部区域进行 ocr 识别,获取识别结果作为新文件名,最后对 pdf 文件进行重命名。
准备工作
注册百度云账号:在百度云官网注册账号并创建 ocr 应用,获取 api key 和 secret key。
安装 qt:确保已经安装了 qt 开发环境。
安装依赖库:需要安装 poppler 用于 pdf 转图片,以及 qnetworkaccessmanager 用于网络请求。
代码实现
1. 创建 qt 项目
创建一个新的 qt widgets application 项目。
2. 界面设计
在 mainwindow.ui 中设计简单的界面,包含一个按钮用于选择 pdf 文件目录,一个文本框用于显示操作结果。
3. 代码实现
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qfiledialog>
#include <qdir>
#include <qprocess>
#include <qnetworkaccessmanager>
#include <qnetworkrequest>
#include <qnetworkreply>
#include <qjsondocument>
#include <qjsonobject>
#include <qjsonarray>
#include <qimage>
#include <qpixmap>
#include <qpainter>
#include <poppler/qt5/poppler-qt5.h>
mainwindow::mainwindow(qwidget *parent)
: qmainwindow(parent)
, ui(new ui::mainwindow)
{
ui->setupui(this);
connect(ui->selectdirbutton, &qpushbutton::clicked, this, &mainwindow::selectdirectory);
networkmanager = new qnetworkaccessmanager(this);
connect(networkmanager, &qnetworkaccessmanager::finished, this, &mainwindow::onnetworkreplyfinished);
}
mainwindow::~mainwindow()
{
delete ui;
}
void mainwindow::selectdirectory()
{
qstring dir = qfiledialog::getexistingdirectory(this, tr("select directory"), "", qfiledialog::showdirsonly | qfiledialog::dontresolvesymlinks);
if (!dir.isempty()) {
qdir directory(dir);
qstringlist filters;
filters << "*.pdf";
qstringlist pdffiles = directory.entrylist(filters, qdir::files);
for (const qstring &pdffile : pdffiles) {
qstring pdfpath = directory.filepath(pdffile);
processpdf(pdfpath);
}
}
}
void mainwindow::processpdf(const qstring &pdfpath)
{
poppler::document *document = poppler::document::load(pdfpath);
if (!document || document->islocked()) {
ui->resulttextedit->append("failed to load pdf: " + pdfpath);
delete document;
return;
}
poppler::page *page = document->page(0);
if (!page) {
ui->resulttextedit->append("failed to get page from pdf: " + pdfpath);
delete document;
return;
}
qimage image = page->rendertoimage();
// 假设我们要提取的局部区域(这里需要根据实际情况调整)
qrect region(100, 100, 200, 50);
qimage croppedimage = image.copy(region);
qbytearray imagedata;
qbuffer buffer(&imagedata);
buffer.open(qiodevice::writeonly);
croppedimage.save(&buffer, "jpeg");
buffer.close();
qstring apikey = "your_api_key";
qstring secretkey = "your_secret_key";
qstring tokenurl = qstring("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%1&client_secret=%2").arg(apikey).arg(secretkey);
qnetworkrequest tokenrequest(qurl(tokenurl));
networkmanager->get(tokenrequest);
pdfpaths.append(pdfpath);
imagedatas.append(imagedata);
delete page;
delete document;
}
void mainwindow::onnetworkreplyfinished(qnetworkreply *reply)
{
if (reply->error() == qnetworkreply::noerror) {
qbytearray responsedata = reply->readall();
qjsondocument jsondoc = qjsondocument::fromjson(responsedata);
qjsonobject jsonobj = jsondoc.object();
if (jsonobj.contains("access_token")) {
qstring accesstoken = jsonobj["access_token"].tostring();
if (!pdfpaths.isempty() && !imagedatas.isempty()) {
qstring pdfpath = pdfpaths.takefirst();
qbytearray imagedata = imagedatas.takefirst();
qstring ocrurl = qstring("https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=%1").arg(accesstoken);
qnetworkrequest ocrrequest(qurl(ocrurl));
ocrrequest.setheader(qnetworkrequest::contenttypeheader, "application/x-www-form-urlencoded");
qbytearray postdata;
postdata.append("image=").append(qurl::topercentencoding(imagedata.tobase64()));
networkmanager->post(ocrrequest, postdata);
}
} else if (jsonobj.contains("words_result")) {
qjsonarray wordsresult = jsonobj["words_result"].toarray();
qstring newfilename;
for (const auto &result : wordsresult) {
qjsonobject wordobj = result.toobject();
newfilename += wordobj["words"].tostring();
}
if (!pdfpaths.isempty()) {
qstring pdfpath = pdfpaths.takefirst();
qfileinfo fileinfo(pdfpath);
qstring newfilepath = fileinfo.dir().filepath(newfilename + ".pdf");
qfile::rename(pdfpath, newfilepath);
ui->resulttextedit->append("renamed: " + pdfpath + " to " + newfilepath);
}
}
} else {
ui->resulttextedit->append("network error: " + reply->errorstring());
}
reply->deletelater();
}4. 头文件 mainwindow.h
cpp
#ifndef mainwindow_h
#define mainwindow_h
#include <qmainwindow>
#include <qnetworkaccessmanager>
#include <qlist>
qt_begin_namespace
namespace ui { class mainwindow; }
qt_end_namespace
class mainwindow : public qmainwindow
{
q_object
public:
mainwindow(qwidget *parent = nullptr);
~mainwindow();
private slots:
void selectdirectory();
void onnetworkreplyfinished(qnetworkreply *reply);
private:
ui::mainwindow *ui;
qnetworkaccessmanager *networkmanager;
qlist<qstring> pdfpaths;
qlist<qbytearray> imagedatas;
void processpdf(const qstring &pdfpath);
};
#endif // mainwindow_h

注意事项
请将 your_api_key 和 your_secret_key 替换为你自己的百度云 ocr api key 和 secret key。
代码中假设要提取的局部区域为 qrect(100, 100, 200, 50),你需要根据实际情况
以上就是基于qt和百度云api实现批量获取pdf局部文字内容的详细内容,更多关于qt获取pdf局部内容的资料请关注代码网其它相关文章!
发表评论