当前位置: 首页 > news >正文

java通过ocr实现识别pdf中的文字

需求:识别pdf文件中的中文

根据github项目mymonstercat 改造,先将pdf文件转为png文件存于临时文件夹,然后通过RapidOcr转为文字,最后删除临时文件夹

1、引入依赖

		<dependency><groupId>org.apache.pdfbox</groupId><artifactId>fontbox</artifactId><version>3.0.3</version></dependency><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>3.0.3</version></dependency><!-- ocr图片识别 --><dependency><groupId>io.github.mymonstercat</groupId><artifactId>rapidocr</artifactId><version>0.0.7</version></dependency><dependency><groupId>io.github.mymonstercat</groupId><artifactId>rapidocr-onnx-platform</artifactId><version>0.0.7</version></dependency><!-- 本地测试可不引 , 服务器部署linux x86架构 下引入 ,其他环境部署可搜maven --><dependency><groupId>io.github.mymonstercat</groupId><artifactId>rapidocr-onnx-linux-x86_64</artifactId><version>1.2.2</version></dependency>

2、工具类

import org.springframework.util.StringUtils;
import com.benjaminwan.ocrlibrary.OcrResult;
import com.benjaminwan.ocrlibrary.TextBlock;import io.github.mymonstercat.Model;
import io.github.mymonstercat.ocr.InferenceEngine;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.stereotype.Service;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
@Service
public class PdfOCRConverter {//临时输出png文件路径private static final String outputDirs = "D:/pdfToImg/temp/";public static void main(String[] args) throws IOException {List<String> fileNameList = getWords("D:/Download/123.pdf");for (String fileName : fileNameList) {System.out.println(fileName);}}public static List<String> getWords(String pdfFilePath) throws IOException {String outputDir =  outputDirs + UUID.randomUUID().toString().replace("-", "");List<String> fileNameList = convertPdfToImage(pdfFilePath, outputDir);List<String> wordsList = new ArrayList<>();for (String fileName : fileNameList) {System.out.println("识别图片:"+fileName);if (StringUtils.isEmpty(fileName)){break;}List<String> words = runOcr(fileName);for (String word : words) {System.out.println(word);wordsList.add(word);}}deleteDirectory(outputDir);return wordsList;}public static List<String> runOcr(String path) {List<String> results = new ArrayList<>();InferenceEngine engine = InferenceEngine.getInstance(Model.ONNX_PPOCR_V3);OcrResult ocrResult = engine.runOcr(path);for (TextBlock textBlock : ocrResult.getTextBlocks()) {results.add(textBlock.getText());}return results;}public static List<String> convertPdfToImage(String pdfFilePath, String outputDir) {// 设置DPI(越高图片越清晰,但文件也会更大)int dpi = 300;List<String> fileNameList = new ArrayList<>();File file = new File(pdfFilePath);try (PDDocument document = Loader.loadPDF(file)) {PDFRenderer pdfRenderer = new PDFRenderer(document);String pdfFileName = file.getName().replace(".pdf", "");String name = pdfFileName;for (int page = 0; page < document.getNumberOfPages(); page++) {BufferedImage bim = pdfRenderer.renderImageWithDPI(page, dpi);String folder = createFolder(outputDir + "/" + name);String fileName = folder + "/" + pdfFileName + "_page_" + (page + 1) + ".png";ImageIO.write(bim, "png", new File(fileName));fileNameList.add(fileName);System.out.println("生成图片:"+fileName);}} catch (IOException e) {e.printStackTrace();}return fileNameList;}public static void deleteDirectory(String path) throws IOException {// 如果路径不指向一个目录,则抛出异常Path directory = Paths.get(path);if (!Files.isDirectory(directory)) {throw new IOException("The provided path is not a directory.");}// 遍历目录中的所有文件和子目录Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {// 删除文件Files.delete(file);return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {// 所有内容被删除后删除目录本身Files.delete(dir);return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {// 如果访问文件失败,则抛出异常throw exc;}});}public static String createFolder(String folderPath) {String txt = folderPath;try {File myFilePath = new File(txt);txt = folderPath;if (!myFilePath.exists()) {myFilePath.mkdirs();}} catch (Exception e) {e.printStackTrace();}return txt;}public static List<String> getWordsByBase64(String base64) throws IOException {List<String> words = new ArrayList<>();if (StringUtils.isEmpty(base64)) {return null;}String outputDir = outputDirs + UUID.randomUUID().toString().replace("-", "");// 解码Base64字符串byte[] decodedBytes = Base64.getDecoder().decode(base64);createFolder(outputDir);// 输出的PDF文件名String outputFilePath = outputDir+"/output.pdf";try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {// 将解码后的字节数组写入文件fos.write(decodedBytes);System.out.println("PDF文件已成功生成: " + outputFilePath);words = getWords(outputFilePath);} catch (Exception e) {e.printStackTrace();}deleteDirectory(outputDir);return words;}}

相关文章:

java通过ocr实现识别pdf中的文字

需求&#xff1a;识别pdf文件中的中文 根据github项目mymonstercat 改造,先将pdf文件转为png文件存于临时文件夹&#xff0c;然后通过RapidOcr转为文字,最后删除临时文件夹 1、引入依赖 <dependency><groupId>org.apache.pdfbox</groupId><artifactId&g…...

Git 命令代码管理详解

一、Git 初相识&#xff1a;版本控制的神器 在当今的软件开发领域&#xff0c;版本控制如同基石般重要&#xff0c;而 Git 无疑是其中最耀眼的明珠。它由 Linus Torvalds 在 2005 年创造&#xff0c;最初是为了更好地管理 Linux 内核源代码。随着时间的推移&#xff0c;Git 凭借…...

Docker的安装和使用

容器技术 容器与虚拟机的区别 虚拟机 (VM) VM包含完整的操作系统&#xff0c;并在虚拟化层之上运行多个操作系统实例。 VM需要更多的系统资源&#xff08;CPU、内存、存储&#xff09;来管理这些操作系统实例。 容器 (Container) 容器共享主机操作系统的内核&#xff0c;具…...

Flink系统知识讲解之:Flink内存管理详解

Flink系统知识讲解之&#xff1a;Flink内存管理详解 在现阶段&#xff0c;大部分开源的大数据计算引擎都是用Java或者是基于JVM的编程语言实现的&#xff0c;如Apache Hadoop、Apache Spark、Apache Drill、Apache Flink等。Java语言的好处是不用考虑底层&#xff0c;降低了程…...

使用JMeter模拟多IP发送请求!

你是否曾遇到过这样的场景&#xff1a;使用 JMeter 进行压力测试时&#xff0c;单一 IP 被服务器限流或者屏蔽&#xff1f;这时&#xff0c;如何让 JMeter 模拟多个 IP 发送请求&#xff0c;成功突破测试限制&#xff0c;成为测试工程师必须攻克的难题。今天&#xff0c;我们就…...

【Ubuntu与Linux操作系统:六、软件包管理】

第6章 软件包管理 6.1 Linux软件安装基础 Linux的软件包是以二进制或源码形式发布的程序集合&#xff0c;包含程序文件和元数据。软件包管理器是Linux系统的重要工具&#xff0c;用于安装、更新和卸载软件。 1. 常见的软件包管理器&#xff1a; DEB 系统&#xff08;如Ubunt…...

【数据结构-堆】力扣1834. 单线程 CPU

给你一个二维数组 tasks &#xff0c;用于表示 n​​​​​​ 项从 0 到 n - 1 编号的任务。其中 tasks[i] [enqueueTimei, processingTimei] 意味着第 i​​​​​​​​​​ 项任务将会于 enqueueTimei 时进入任务队列&#xff0c;需要 processingTimei 的时长完成执行。 现…...

【前端动效】原生js实现拖拽排课效果

目录 1. 效果展示 2. 效果分析 2.1 关键点 2.2 实现方法 3. 代码实现 3.1 html部分 3.2 css部分 3.3 js部分 3.4 完整代码 4. 总结 1. 效果展示 如图所示&#xff0c;页面左侧有一个包含不同课程&#xff08;如语文、数学等&#xff09;的列表&#xff0c;页面右侧…...

C#使用OpenTK绘制3D可拖动旋转图形三棱锥

接上篇,绘制着色矩形 C#使用OpenTK绘制一个着色矩形-CSDN博客 上一篇安装OpenTK.GLControl后,这里可以直接拖动控件GLControl 我们会发现GLControl继承于UserControl //// 摘要:// OpenGL-aware WinForms control. The WinForms designer will always call the default//…...

排序的本质、数据类型及算法选择

排序的本质、数据类型及算法选择 一、排序的本质二、排序的数据类型三、排序算法的选择依据 前两天老金写了篇 “十大排序简介”&#xff0c;有点意犹未尽&#xff0c;这一回老金想把排序连根拔起&#xff0c;从排序的本质说道说道。 一、排序的本质 从字面上理解&#xff0c…...

Python的列表基础知识点(超详细流程)

目录 一、环境搭建 二、列表 2.1 详情 2.2 列表定义 2.3 列表长度 2.4 列表索引 2.5 切片索引 2.6 添加 2.7 插入 2.8 剔除 2.8.1 pop方法 2.8.2 del方法 2.9 任何数据类型 2.10 拼接 2.10.1 “” 2.10.2 “*” 2.11 逆序 ​编辑 2.12 计算出现次数 2.13 排序…...

HarmonyOS鸿蒙开发 弹窗及加载中指示器HUD功能实现

HarmonyOS鸿蒙开发 弹窗及加载中指示器HUD功能实现 最近在学习鸿蒙开发过程中&#xff0c;阅读了官方文档&#xff0c;在之前做flutter时候&#xff0c;经常使用overlay&#xff0c;使用OverlayEntry加入到overlayState来做添加悬浮按钮、提示弹窗、加载中指示器、加载失败的t…...

【Ubuntu与Linux操作系统:一、Ubuntu安装与基本使用】

第1章 Ubuntu安装与基本使用 1.1 Linux与Ubuntu Linux是一种开源、类Unix操作系统内核&#xff0c;拥有高稳定性和强大的网络功能。由于其开源性和灵活性&#xff0c;Linux被广泛应用于服务器、嵌入式设备以及桌面环境中。 Ubuntu是基于Debian的一个流行Linux发行版&#xf…...

React 元素渲染

React 元素渲染 React 是一个用于构建用户界面的 JavaScript 库&#xff0c;它允许开发人员创建大型应用程序&#xff0c;这些应用程序可以随着时间的推移而高效地更新和渲染。React 的核心概念之一是元素渲染&#xff0c;它描述了如何将 JavaScript 对象转换为 DOM&#xff0…...

【2024年华为OD机试】 (C卷,100分)- 括号匹配(Java JS PythonC/C++)

一、问题描述 题目描述 给定一个字符串&#xff0c;里边可能包含“()”、“[]”、“{}”三种括号&#xff0c;请编写程序检查该字符串中的括号是否成对出现&#xff0c;且嵌套关系正确。 若括号成对出现且嵌套关系正确&#xff0c;或该字符串中无括号字符&#xff0c;输出&am…...

解锁企业数字化转型新力量:OpenCoze(开源扣子)

在当今数字化浪潮席卷之下&#xff0c;企业对于高效管理和协同运作的需求愈发迫切&#xff0c;而开源技术正逐渐成为众多企业破局的关键利器。今天&#xff0c;想给大家介绍一款极具潜力的开源项目 ——OpenCoze&#xff0c;中文名称 “开源扣子”。 一、OpenCoze 是什么&…...

【网络云SRE运维开发】2025第2周-每日【2025/01/12】小测-【第12章 rip路由协议】理论和实操考试题解析

文章目录 选择题答案及解析理论题答案及解析实操题答案及解析下一步进阶 选择题答案及解析 RIP路由协议是基于哪种算法的动态路由协议&#xff1f; 答案&#xff1a;B. 距离矢量算法解析&#xff1a;链路状态算法用于OSPF等协议&#xff1b;最小生成树算法主要用于生成树协议&…...

【微服务】8、分布式事务 ( XA 和 AT )

文章目录 利用Seata解决分布式事务问题&#xff08;XA模式&#xff09;AT模式1. AT模式原理引入2. AT模式执行流程与XA模式对比3. AT模式性能优势及潜在问题4. AT模式数据一致性解决方案5. AT模式一阶段操作总结6. AT模式二阶段操作分析7. AT模式整体特点8. AT模式与XA模式对比…...

CVE-2025-22777 (CVSS 9.8):WordPress | GiveWP 插件的严重漏洞

漏洞描述 GiveWP 插件中发现了一个严重漏洞&#xff0c;该插件是 WordPress 最广泛使用的在线捐赠和筹款工具之一。该漏洞的编号为 CVE-2025-22777&#xff0c;CVSS 评分为 9.8&#xff0c;表明其严重性。 GiveWP 插件拥有超过 100,000 个活跃安装&#xff0c;为全球无数捐赠平…...

TypeScript Jest 单元测试 搭建

NPM TypeScript 项目搭建 创建目录 mkdir mockprojectcd mockproject初始化NPM项目 npm init -y安装TypeScript npm i -D typescript使用VSCode 打开项目 创建TS配置文件tsconfig.json {"compilerOptions": {"target": "es5","module&…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...