76、使用spire.doc获取pdf中的图片,使用tesseract-ocr读取图片中的内容
需求:解析pdf中的图片,拿到指定的内容;
1、tesseract-ocr 简介:
ocr 含义是Optical Character Recognition,含义即视觉字符识别。而tesseract是该领域特别优秀开源的作品。
实现流程如下所示:
关于tesseract的工作模式如上图所示。假设现在有一个图片输入,整个执行流程为:
1:输入(一张图片)
2:有用信息提取(比如一个图片上只有一个字,那其他留白的是无用,这个字上每个色素是有效的并且相关)
3:找出文字/线条
4:字符分类集
5:输入与分类集对比找出最接近的
6:输出识别结果
2、安装tessearact
下载连接如下所示:
安装连接:https://digi.bib.uni-mannheim.de/tesseract/
尽量不要下载dev(开发中的版本),alpha(内部测试版,一般不向外部发布,会有很多Bug),beta(公测版本,即针对所有用户公开的测试版本)等版本。
出现一堆下载失败(语言包下载有问题,挂了vpn之后可以正常下载了)
一直确定,直到安装成功
可以去github上下载语言安装包,然后放置到tessdata文件夹下面
地址:https://gitcode.net/mirrors/tesseract-ocr/tessdata?utm_source=csdn_github_accelerator
挂了vpn之后,下载如下所示
配置环境变量
打开cmd窗口,输入 tesseract -v显示版本号,即成功
查看安装的语言包
在cmd中输入tesseract --list-langs回车,若显示版本号即为安装成功。
安装失败:
失败原因:Please make sure the TESSDATA_PREFIX environment variable is set to your “tessdata“ directory.
新增环境变量:TESSDATA_PREFIX 值:D:\Tesseract-OCR\tessdata (安装路径)
cmd窗口重新运行,即可成功显示语言
解析ocr 代码
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* 调用ocr
*
* @author LZH
* @version 1.0
* @date 2023/04/03 15:12:51
*/
public class OCRUtil {
private final String LANG_OPTION = "-l"; //英文字母小写l,并非阿拉伯数字1
private final String EOL = System.getProperty("line.separator");
private String tessPath = "D://Tesseract-OCR";//ocr的安装路径
public OCRUtil(String tessPath,String transFileName){
this.tessPath=tessPath;
}
//OCRUtil的构造方法,默认路径是"C://Program Files (x86)//Tesseract-OCR"
public OCRUtil(){ }
public String getTessPath() {
return tessPath;
}
public void setTessPath(String tessPath) {
this.tessPath = tessPath;
}
public String getLANG_OPTION() {
return LANG_OPTION;
}
public String getEOL() {
return EOL;
}
//可以自定义语言
public String recognizeText(File imageFile)throws Exception{
return ocrImages(imageFile);
}
/**
* @param imageFile
* @return 识别后的内容
* @throws IOException
* @throws InterruptedException
*/
private String ocrImages(File imageFile) throws IOException, InterruptedException{
// //设置输出文件的保存的文件目录,以及文件名
File outputFile = new File(imageFile.getParentFile(),"test");
StringBuffer strB = new StringBuffer();
//
//
//设置命令行内容
List<String> cmd = new ArrayList<String>();
// if(OS.isWindowsXP()){
// cmd.add(tessPath+"//tesseract");
// }else if(OS.isLinux()){
// cmd.add("tesseract");
// }else{
cmd.add(tessPath+"//tesseract");
// }
cmd.add(imageFile.getName());
cmd.add(outputFile.getName());
cmd.add(LANG_OPTION);
cmd.add("chi_sim");//中文包
cmd.add("equ");//常用数学公式包
cmd.add("eng");//英语包
//
//
// //创建操作系统进程
ProcessBuilder pb = new ProcessBuilder();
pb.directory(imageFile.getParentFile().getAbsoluteFile());//设置此进程生成器的工作目录
// cmd.set(1, tempImage.getName());
// cmd.set(1, imageFile.getName());
pb.command(cmd);//设置要执行的cmd命令
pb.redirectErrorStream(true);//设置后续子进程生成的错误输出都将与标准输出合并
long startTime = System.currentTimeMillis();
System.out.println("开始时间:" + startTime);
Process process = pb.start();//开始执行,并返回进程实例
// Runtime runtime = Runtime.getRuntime();
// Process process = runtime.exec("D:\\Tesseract-OCR\\tesseract D:\\提取的图片\\图片-1.png D:\\提取的图片\\test -l chi_sim+equ+eng");
//最终执行命令为:tesseract 1.png test -l chi_sim+equ+eng
// long startTime = System.currentTimeMillis();
// System.out.println("开始时间:" + startTime);
int w = process.waitFor();
// tempImage.delete();//删除临时正在工作文件
if(w==0){ // 0代表正常退出
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(outputFile.getAbsolutePath()+".txt"),"UTF-8"));
String str;
while((str = in.readLine())!=null){
if (str.contains("号")||str.contains(":")){
strB.append(str).append(EOL).append(";");
}else {
strB.append(str).append(EOL);
}
}
in.close();
long endTime = System.currentTimeMillis();
System.out.println("结束时间:" + endTime);
System.out.println("耗时:" + (endTime - startTime) + "毫秒");
}else{
String msg;
switch(w){
case 1:
msg = "Errors accessing files.There may be spaces in your image's filename.";
break;
case 29:
msg = "Cannot recongnize the image or its selected region.";
break;
case 31:
msg = "Unsupported image format.";
break;
default:
msg = "Errors occurred.";
}
outputFile.delete();
throw new RuntimeException(msg);
}
// new File(outputFile.getAbsolutePath()+".txt");//.delete();
outputFile.delete();
return strB.toString().replaceAll("\\s*", "");
}
}
把文件转换成pdf,然后解析其中内容
public static void main(String[] args) throws Exception {
// 提取pdf中的图片
// 创建 PdfDocument 类的对象
PdfDocument doc = new PdfDocument();
//载入PDF文档
doc.loadFromFile("D:\\test\\1.pdf");
//声明一个int变量
int index = 0;
//
String filePath = "D:/提取的图片/图片-";
// //循环遍历所有页面
for (PdfPageBase page : (Iterable<PdfPageBase>) doc.getPages()) {
//从页面中提取图片
for (BufferedImage image : page.extractImages()) {
//指定文件路径和文件名
File output = new File("D:/提取的图片/" + String.format("图片-%d.png", index++));
//将图片保存为PNG文件
ImageIO.write(image, "PNG", output);
}
if (index >1 )
break;
}
try {
//图片文件:此图片是需要被识别的图片路径
File file = new File(filePath+"1.png");
String recognizeText = new OCRUtil().recognizeText(file);
System.out.print(recognizeText + "\t");
} catch (Exception e) {
e.printStackTrace();
}
}