基本思路

直接用工具将扫描型pdf转文本是不行的,因为扫描型的pdf是图片。先读取整个pdf文件按页生成图片,在调用OCR识别读取文字即可。

pdf第三方库pdfbox

依赖:

        <!--pdfbox pdf解析--><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.1</version></dependency>

使用该库可对pdf文件进行基本读写操作

File file = new File(PdfFilePath);
//加载pdf,可对其进行基本读写
PDDocument pdDocument = PDDocument.load(file);
int pages =pdDocument.getNumberOfPages();// 获取PDF页数
//pdf renderer 渲染器,可转成图片读取
PDFRenderer renderer = new PDFRenderer(pdDocument);
BufferedImage image = renderer.renderImageWithDPI(i, dpi);//i为页数,dpi为精度,默认96

从pdf中读取文本

    /*** 指定pdf与目标文件路径,从pdf文件读取文本到指定文件* @param pdfPath pdf文件路径,绝对路径* @param targetPath 目标文件,绝对路径*/public static void readTextFromPdf(String pdfPath,String targetPath)  {//pdf文件校验File pdfFile=new File(pdfPath);if(!pdfFile.exists()){System.out.println("pdf文件未发现:"+pdfPath);return;}File targetFile=new File(targetPath);PDDocument pdDocument=null;try{//读取文档pdDocument=PDDocument.load(pdfFile);//获取文档页码int pages=pdDocument.getNumberOfPages();//读取文档内容并设置读取参数PDFTextStripper stripper=new PDFTextStripper();stripper.setSortByPosition(true);stripper.setStartPage(1);stripper.setEndPage(pages);String content=stripper.getText(pdDocument);//校验目标文件if(targetFile.exists()){System.out.println("文件已存在,将覆盖文件");}else {System.out.println("目标文件不存在,新建文件");targetFile.createNewFile();}//写入目标文件FileWriter fileWriter=new FileWriter(targetFile);fileWriter.write(content);}catch (Exception e){e.printStackTrace();}System.out.println("写入文件成功");}

将pdf转换为图片

    /*** PDF文件转PNG/JPEG图片* @param PdfFilePath 完整路径* @param dstImgFolder 图片存放的文件夹* @param dpi dpi越大转换后越清晰,相对转换速度越慢,一般电脑默认96dpi*/public static void pdf2Image(String PdfFilePath,String dstImgFolder,int dpi) {File file = new File(PdfFilePath);PDDocument pdDocument;try {//获取pdf文件名称与上层路径String imgPDFPath = file.getParent();int dot = file.getName().lastIndexOf('.');// 获取图片文件名String imagePDFName = file.getName().substring(0, dot);String imgFolderPath = null;if (dstImgFolder.equals("")) {// 获取图片存放的文件夹路径imgFolderPath = imgPDFPath + File.separator + imagePDFName;} else {imgFolderPath = dstImgFolder + File.separator + imagePDFName;}if (createDirectory(imgFolderPath)) {pdDocument = PDDocument.load(file);PDFRenderer renderer = new PDFRenderer(pdDocument);int pages =pdDocument.getNumberOfPages();// 获取PDF页数System.out.println("PDF page number is:" + pages);StringBuffer imgFilePath = null;for (int i = 0; i < pages; i++) {String imgFilePathPrefix = imgFolderPath+ File.separator + imagePDFName;imgFilePath = new StringBuffer();imgFilePath.append(imgFilePathPrefix);imgFilePath.append("_");imgFilePath.append(String.valueOf(i + 1));imgFilePath.append(".png");// PNGFile dstFile = new File(imgFilePath.toString());BufferedImage image = renderer.renderImageWithDPI(i, dpi);ImageIO.write(image, "png", dstFile);// PNG}System.out.println("PDF文档转PNG图片成功!");} else {System.out.println("PDF文档转PNG图片失败:"+ "创建" + imgFolderPath + "失败");}} catch (IOException e) {e.printStackTrace();}}private static boolean createDirectory(String folder) {File dir = new File(folder);if (dir.exists()) {return true;} else {return dir.mkdirs();}}

使用百度API进行OCR识别

登录百度AI开放平台,选择文字识别→通用文字识别

选择文字识别创建应用,三个用于权鉴的必要参数:AppID,AppKey,SecretKey

官方文档:百度AI文字识别文档

请注意不同的场景的免费额度限制

权鉴获取token

/*** @Author lsl* @Date 2020/12/15 9:00** 百度API OCR 文字识别客户端* 用于配置权鉴认证*/
public abstract class ApiOcrClient {//设置APPID/AK/SK,注意替换为自己的public static final String APP_ID = "2**...";// 官网获取的 API Key 更新为你注册的public static final String API_KEY = "i**...";// 官网获取的 Secret Key 更新为你注册的public static final String SECRET_KEY = "**...";//标准版通用文字识别,50000次/天public static final String GENERAL_BASIC_URL="https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic";/*** 子类可使用的客户端,用于连接*/protected static AipOcr client=new AipOcr(APP_ID, API_KEY, SECRET_KEY);/*** 获取权限token* @return 返回示例:* {* "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",* "expires_in": 2592000* }*/public static String getAuth() {return getAuth(API_KEY, SECRET_KEY);}/*** 获取API访问token* 该token有一定的有效期,需要自行管理,当失效时需重新获取.* @param ak - 百度云官网获取的 API Key* @param sk - 百度云官网获取的 Securet Key* @return assess_token 示例:* "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"*/public static String getAuth(String ak, String sk) {// 获取token地址String authHost = "https://aip.baidubce.com/oauth/2.0/token?";String getAccessTokenUrl = authHost// 1. grant_type为固定参数+ "grant_type=client_credentials"// 2. 官网获取的 API Key+ "&client_id=" + ak// 3. 官网获取的 Secret Key+ "&client_secret=" + sk;try {URL realUrl = new URL(getAccessTokenUrl);// 打开和URL之间的连接HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();connection.setRequestMethod("GET");connection.connect();// 获取所有响应头字段Map<String, List<String>> map = connection.getHeaderFields();// 遍历所有的响应头字段for (String key : map.keySet()) {System.err.println(key + "--->" + map.get(key));}// 定义 BufferedReader输入流来读取URL的响应BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));StringBuilder result = new StringBuilder();String line;while ((line = in.readLine()) != null) {result.append(line);}/*** 返回结果示例*/System.err.println("result:" + result);JSONObject jsonObject = new JSONObject(result.toString());return jsonObject.getString("access_token");} catch (Exception e) {System.err.print("获取token失败!");e.printStackTrace(System.err);}return null;}
}

文字识别返回结果

/*** @Author lsl* @Date 2020/11/9 13:49** 百度API文字识别返回响应,返回数据以行为单位*/
public class ApiOcrRes {private String logId;/** 返回结果集,wordResult代表一行 */private List<WordResult> wordsResult;/** 行数 */private int wordsResultNum;public String getLogId() {return logId;}public void setLogId(String logId) {this.logId=logId;}public List<WordResult> getWordsResult() {return wordsResult;}public void setWordsResult(List<WordResult> wordsResult) {this.wordsResult=wordsResult;}public int getWordsResultNum() {return wordsResultNum;}public void setWordsResultNum(int wordsResultNum) {this.wordsResultNum=wordsResultNum;}
}
/*** 每行识别结果*/
class WordResult{private String words;public String getWords() {return words;}public void setWords(String words) {this.words = words;}
}

识别图片

注意要继承上面的抽象父类以获取token

/*** 百度AI OCR文字识别,注意每天访问次数与accessToken过期时间* @param imgPath 本地图片路径* @param url 百度API URL* @param accessToken 百度API 访问Token* @return 识别结果*/
public static String baiduAiOcrGeneralBasic(String imgPath,String url,String accessToken) {try {/*** 重要提示代码中所需工具类* FileUtil,Base64Util,HttpUtil,GsonUtils请从* https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72* https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2* https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3* https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3* 下载*/byte[] imgData = FileUtil.readFileByBytes(imgPath);String imgStr = Base64Util.encode(imgData);String imgParam = URLEncoder.encode(imgStr, "UTF-8");String param = "image=" + imgParam;//发起请求String result = HttpUtil.post(url, accessToken, param);//JSON转换ApiOcrRes apiOcrRes = JSON.parseObject(result, ApiOcrRes.class);StringBuilder res=new StringBuilder();System.out.println("识别结果行数:"+apiOcrRes.getWordsResultNum());if(apiOcrRes.getWordsResult()!=null){for (WordResult words : apiOcrRes.getWordsResult()) {res.append(words.getWords()).append("\n");}}return res.toString();} catch (Exception e) {e.printStackTrace();}return null;
}/*** 将指定图片文件转换成文本并返回字符串* 带位置高精度识别,访问次数500/天** @param imgPath 图片文件* @return 识别结果*/
public static String ImgToText(String imgPath) {if (imgPath == null || imgPath.length() == 0 || !new File(imgPath).exists() || !new File(imgPath).isFile()) {System.out.println("文件不存在");return "";}//返回结果StringBuilder res = new StringBuilder();// 传入可选参数调用接口HashMap<String, String> options = new HashMap<>();options.put("detect_direction", "true");//ocr识别 参数为本地图片路径 获取OCR识别结果JSONObject resOcr = client.basicAccurateGeneral(imgPath, options);//JSON转换ApiOcrRes apiOcrRes = JSON.parseObject(resOcr.toString(), ApiOcrRes.class);System.out.println("识别结果:"+apiOcrRes.getWordsResultNum());if(apiOcrRes.getWordsResult()!=null){for (WordResult words : apiOcrRes.getWordsResult()) {res.append(words.getWords()).append("\n");}}return res.toString();
}

封装-识别图片目录

/*** 将指定图片目录的所有图片文件转换成文本到指定文本文件** @param imgDirPath 图片目录,按顺序识别所有图片* @param textPath   目标文本文件路径* @param comparator 比较器,目录下图片的排序规则*/
public static void ImgDirToText(String imgDirPath, String textPath, Comparator<File> comparator) {//图片目录校验File imgDir = new File(imgDirPath);if (!imgDir.exists() || !imgDir.isDirectory()) {System.out.println("错误:图片目录不存在或是文件");return;}//目标文本文件File textFile = new File(textPath);try {if (!textFile.exists() && !textFile.createNewFile()) {System.out.println("创建目标文件失败");return;}FileWriter fileWriter = new FileWriter(textFile);//遍历图片目录,按照顺序规则严格指定File[] imgFiles = imgDir.listFiles();//指定排序规则Arrays.sort(imgFiles, comparator);//获取TokenString accessToken=getAuth();for (File file : imgFiles) {System.out.println("开始将图片转换为文本:" + file.getAbsolutePath());//获取OCR识别结果String res = baiduAiOcrGeneralBasic(file.getAbsolutePath(),GENERAL_BASIC_URL,accessToken);//写入文件fileWriter.write(res);}//关闭文件fileWriter.close();} catch (Exception e) {e.printStackTrace();}
}

封装-使用测试

注意按照生成图片命名规则来构造比较器

    @Testpublic void imgDirToText() {Comparator comparator=new Comparator<File>() {@Overridepublic int compare(File o1, File o2) {String a1=o1.getAbsolutePath();String a2=o2.getAbsolutePath();a1=a1.substring(a1.indexOf('_')+1,a1.indexOf('.'));a2=a2.substring(a2.indexOf('_')+1,a2.indexOf('.'));return Integer.parseInt(a1)-Integer.parseInt(a2);}};Image2Text.ImgDirToText("E:\\新建文件夹","E:\\ctf特训营1.txt",comparator);}

图片型pdf转文本文档相关推荐

  1. PDF文件如何转换成txt文本文档

    想要将PDF文件转换成txt文本文档,需要用到PDF转换器的帮助,比如奥凯丰 PDF转换大师将PDF文件格式转换一下. [PDF转换大师]转为word_excel_ppt_txt_jpg等格式-奥凯丰 ...

  2. 从TXT文本文档向Sql Server中批量导入数据

    因为工作的需要,近期在做数据的分析和数据的迁移.在做数据迁移的时候需要将原有的数据导入到新建的数据库中.本来这个单纯的数据导入导出是没有什么问题的,但是客户原有的数据全部都是存在.dat文件中的.所以 ...

  3. 如何把文本文档转换成html格式,把固定格式的文本文档转换为Excel电子表格的方法...

    有时候,需要把一些拥有固定格式的文本文件导入电子表格.微软的Excel 电子表格程序有一个文本文件转换向导,将这种格式转换变得非常快捷方便.本文图文讲解把固定格式的文本文档转换为Excel电子表格的方 ...

  4. 如何将多个文本文档合并到一个文档中?

    2019独角兽企业重金招聘Python工程师标准>>> 在日常工作中,我们需要将多个文本文档合并到一个中,接下来将介绍一种批处理的方法. 工具/原料 文本文档 方法/步骤 如图所示, ...

  5. win10右键新建没有文本文档

    点击开始找到电脑附件,如图所示: 二.将下面代码放到文本保存为txtfile.reg 文件,保存到桌面,双击提示是否,点击就是变可以,然后你右击后你会发现你文本文档回来了 Windows Regist ...

  6. 新建一个文本文档,将后缀改为html,却还是文本文档格式,且后缀有txt

    问题描述: 如图,在文本文档中写好网页代码,然后加后缀html,结果还是txt文档. 解决方法: 1.在文件夹点开或者直接在左下角搜索此电脑 2.点开此电脑,在顶部找到"查看".点 ...

  7. 《新建文本文档》贾瑜

    我的笔记本电脑出了点问题,苦笑不得. 2010年花了6000元买的机器,重装了约7次系统,最后稳定在现在这个舆论口碑很差的VISTA系统.但我用了大概一年左右,再也没出过问题, 虽然慢是慢了点,好在稳 ...

  8. 在线文本文档txt编辑器_审查了6位在线文档和文本编辑者

    在线文本文档txt编辑器 Who wants to limit himself to one computer nowadays? Say hello to online editors, where ...

  9. win10新建文本文档(TXT)的快捷键

    默认是没有这个快捷键的,方法在这个网页:飞机票. 最后的任务计划程序部分我没有成功,最后开机会弹出注册表提示,确认就行. 以防万一我截个图防止这个网页消失 Windows Registry Edito ...

最新文章

  1. c++ 重载、重写、重定义(隐藏)
  2. 解决docker中/etc/default/docker配置DOCKER_OPTS 失效问题
  3. php 清除opcache缓存的方法
  4. echarts graph图重叠_借官方关系图尝试下屏蔽鼠标浮在 links 上弹出的提示框
  5. iOS研发助手DoraemonKit技术实现(一)
  6. phpddos***器1.0-6.0
  7. CMSIS-DSP lib 矩阵运算示例和源码
  8. 动态ARP检测原理及应用
  9. 内存超频时序怎么调_憋了很久的问题:内存时序有什么用?超频时怎么调?
  10. 基于Trie树实现拼音搜索自动补全
  11. JAVA并发系列十九:深入理解ThreadLocal(三)–详解ThreadLocal内存泄漏问题
  12. Java的第一个你好世界
  13. 如何下载网页中的视频成mp4格式
  14. Belief Propagation信念传播算法详解
  15. Web前端下载文件的几种常见方式
  16. 邮政储蓄银行厦门分行经营管理系统 项目总结
  17. JS实现多张图片绕中心点转动
  18. 《Cocos Creator游戏实战》实现下拉框按钮ComboBox控件
  19. 同样是IT行业,测试和开发薪资真有这么大差别?
  20. 编程题——Fibonacci数列

热门文章

  1. 南邮 OJ 2026 Keroro侵略地球
  2. win10 pro 使用远程桌面
  3. UI——day6.引导页的设计
  4. 名校博士生临近毕业突然离世!去世前一直在熬夜完善毕业论文...
  5. 图数据库 gStore 1.0 版本正式发布
  6. Android免root投屏远程控制,MK手机远程控制
  7. 学习游戏3D建模电脑推荐,入门级应该怎么学才能做出好看的模型?
  8. ENC28J60学习笔记——第1部分
  9. PIC以太网开发板——基于微芯最新ENC28J60以太网控制器
  10. win10安装ubuntu16.04双系统