使用插件:UMI-OCR、PDFBOX
实现思路:通过PDFBOX识别PDF文字,如果是图片,则识别不出来,再调用OCR进行识别返回文字;OCR识别较慢,长图识别不出来,目前HTTP方式只支持图片格式,还需使用PDFBOX要将每一页PDF转换为图片再进行识别拼接。
UMI-OCR下载地址:https://github.com/hiroi-sora/Umi-OCR/releases/latest
git仓库地址:GitHub - hiroi-sora/Umi-OCR: OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多国语言库。
下载后直接在WIN系统安装(目前只支持WIN系统),安装包内含PaddleOCR-json,无需再进行下载;安装启动,设置HTTP请求参数
全局设置 --> 高级 --> 允许HTTP服务:
主机设置为:任何可用地址
端口:自己设置
PDFBOX MAVEN版本配置:
<!-- PDF文档处理 -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.8</version>
</dependency>
代码实现文字识别:
String text = "";
try {
PDDocument pdDocument = PDDocument.load(image.getInputStream());
PDFTextStripper pdfTextStripper = new PDFTextStripper();
//读取pdf中所有的文件
//前端HTML不识别><,需要进行更换
text = pdfTextStripper.getText(pdDocument);
text = text.replace(" ", "")
.replace("\r", "")
.replace("\t", "")
.replace("\n", "");
if (StrUtil.isNotEmpty(text)){
text = text.replace("<","<").replace(">",">");
}else{
/**
* 如果没有识别到文字,
* 则转成图片
* 进行OCR识别获取文本
*/
text = uploadPDF2OcrGetText(accessUrl, image);
}
}catch (IOException e){
log.error(e.getMessage());
}
如果文档里面含有"<"">",前端HTML不识别,则需要进行转换
uploadPDF2OcrGetText:
/**
* 上传图片文件至OCR
* @param accessUrl 访问地址
* @param image 图片文件
* @return
*/
public static String uploadPDF2OcrGetText(String accessUrl, MultipartFile image) {
List<ByteArrayOutputStream> list = getStreamList(image);
StringBuilder sb = new StringBuilder();
if (list != null && !list.isEmpty()){
for (ByteArrayOutputStream outputStream : list) {
String str = getData(accessUrl, outputStream);
if (StrUtil.isNotEmpty(str)){
sb.append(str);
}
}
}
return sb.toString();
}
将PDF转为图片流方法getStreamList:
/**
* PDFBOX将PDF转成png流
* @param file 图片文件
* @return List
*/
public static List<ByteArrayOutputStream> getStreamList(MultipartFile file) {
List<ByteArrayOutputStream> list = new ArrayList<>();
try{
PDDocument pdf = PDDocument.load(file.getInputStream());
PDFRenderer renderer = new PDFRenderer(pdf);
int pageCount = pdf.getNumberOfPages();
for (int i = 0; i < pageCount; i++){
BufferedImage image = renderer.renderImageWithDPI(i, 120);//120为DPI根据自己设置
ByteArrayOutputStream bas = new ByteArrayOutputStream();
ImageIO.write(image, "png", bas);
list.add(bas);
}
}catch (IOException e){
log.error(e.getMessage());
}
return list;
}
调用OCR识别文字方法getData:
/**
* 上传图片文件至OCR
* @param accessUrl 访问地址
* @param outputStream 图片流
* @return
*/
public static String getData(String accessUrl, ByteArrayOutputStream outputStream){
//转换为Base64
String base64Image = new String(Base64.encodeBase64(outputStream.toByteArray()));
//如果文件属于图片则进行文件转换
JSONObject jb = new JSONObject();
jb.set("base64", base64Image);
JSONObject jb1 = new JSONObject();
jb1.set("tbpu.parser", "multi_para");
jb1.set("data.format", "text");
jb.set("options", jb1);
String result2 = HttpRequest.post(accessUrl)
.body(jb.toString())//表单内容
.timeout(300000)//数据可能较大,超时时间调的较长
.execute().body();
JSONObject jsonObject = JSONUtil.parseObj(result2);
String text = null;
if ("100".equals(jsonObject.getStr("code"))){
text = jsonObject.getStr("data");
}
return text;
}