文章目录
- 简介
- 文件下载
- 引入依赖
- main函数中使用
- 基于Springboot搭建OCR Web服务
- 配置traineddata路径
- 枚举用到的语种类型
- 定义接口响应的json数据格式
- 封装OCR服务引擎
- 编写web提供服务的接口
- 启动服务并且测试
- html demo扩展
- 项目配套代码
简介
- Tess4J是一个基于Tesseract OCR引擎的Java接口,可以用来识别图像中的文本。
- Tesseract是一个开源的光学字符识别(OCR)引擎,它可以将图像中的文字转换为计算机可读的文本。支持多种语言和书面语言,并且可以在命令行中执行。它是一个流行的开源OCR工具,可以在许多不同的操作系统上运行。
文件下载
目前我测试只用到简体中文和英文,所以只下载了两个
简体中文下载
英文下载
其它语种请按需下载
把下载后的文件统一放到一个目录下
引入依赖
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>5.10.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
main函数中使用
public static void main(String[] args) throws Exception {
ITesseract tesseract = new Tesseract();
// 设置训练集文件存储目录
tesseract.setDatapath("D:/traineddata");
// 设置引擎为中文简体 文件名不含后缀
tesseract.setLanguage("chi_sim");
String result = tesseract.doOCR(ImageIO.read(new File("D:\\test\\zh.png")));
System.out.println(result);
// 设置引擎为英文
tesseract.setLanguage("eng");
result = tesseract.doOCR(ImageIO.read(new File("D:\\test\\en.png")));
System.out.println(result);
}
识别结果如下
基于Springboot搭建OCR Web服务
配置traineddata路径
application.yaml中配置如下内容
server:
port: 8036
#ocr引擎存放路径
tess4j:
datapath: D:/traineddata
枚举用到的语种类型
/**
* @Description 自行扩展需要的OCR引擎语种
* @Author Dominick Li
**/
@Getter
@AllArgsConstructor
public enum LanguageTypeEnum {
CHINESE_SIMPLIFIED("chi_sim", "简体中文"),
ENGLISH("eng", "英文");
private final String value;
private final String language;
/**
* 根据语种查找枚举对象
* @param language 前端传的参数
* @return 没找到对应的则默认使用简单中文
*/
public static LanguageTypeEnum getLanguageByType(String language) {
for (LanguageTypeEnum languageTypeEnum : LanguageTypeEnum.values()) {
if (languageTypeEnum.getValue().equals(language)) {
return languageTypeEnum;
}
}
return CHINESE_SIMPLIFIED;
}
}
定义接口响应的json数据格式
@Data
@Builder
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class OcrResult {
/**
* 是否识别成功
*/
public boolean success;
/**
* 识别时间
*/
public long time;
/**
* 识别结果
*/
public String[] texts;
/**
* 异常信息
*/
public String msg;
public static OcrResult success(String text, long time) {
return OcrResult.builder()
.success(true)
.texts(text.split("\n"))
.time(time)
.build();
}
public static OcrResult fail(String msg) {
return OcrResult.builder()
.success(false)
.msg(msg)
.build();
}
}
封装OCR服务引擎
@Slf4j
@Service
public class TesseractServer {
@Value("${tess4j.datapath}")
private String datapath;
private final static Map<LanguageTypeEnum, ITesseract> SERVER_INSTANCE = new HashMap<>();
/**
* 根据枚举配置的语种初始化Tesseract引擎
*/
@PostConstruct
public void init() {
ITesseract iTesseract;
for (LanguageTypeEnum languageTypeEnum : LanguageTypeEnum.values()) {
iTesseract = new Tesseract();
//设置训练集文件存储目录
iTesseract.setDatapath(datapath);
//设置语种
iTesseract.setLanguage(languageTypeEnum.getValue());
SERVER_INSTANCE.put(languageTypeEnum, iTesseract);
log.info("load {} ocr model", languageTypeEnum.getLanguage());
}
}
/**
* ocr识别
*/
private OcrResult doOCR(ITesseract iTesseract, BufferedImage bufferedImage) throws Exception {
String result = null;
long startTime = System.currentTimeMillis();
result = iTesseract.doOCR(bufferedImage);
long time = System.currentTimeMillis()-startTime;
log.info("Time is: {} 毫秒", time);
return OcrResult.success(result, time);
}
public OcrResult ocrImage(LanguageTypeEnum languageTypeEnum, File file) throws Exception {
return doOCR(SERVER_INSTANCE.get(languageTypeEnum), ImageIO.read(file));
}
public OcrResult ocrImage(LanguageTypeEnum languageTypeEnum, MultipartFile file) throws Exception {
return ocrImage(languageTypeEnum, ImageIO.read(new ByteArrayInputStream(file.getBytes())));
}
public OcrResult ocrImage(LanguageTypeEnum languageTypeEnum, BufferedImage bufferedImage) throws Exception {
return doOCR(SERVER_INSTANCE.get(languageTypeEnum), bufferedImage);
}
}
编写web提供服务的接口
@Slf4j
@RestController
@RequestMapping("/api")
public class OcrController {
@Resource
private TesseractServer tesseractServer;
/**
* OCR识别 /ocr/chi_sim /ocr/eng
* @param language 使用的模型语种 chi_sim=简体中文 eng=英文
* @param file 需要识别的图片
*/
@PostMapping("/ocr/{language}")
public OcrResult recognize(@PathVariable String language, MultipartFile file) {
try {
// 对图片进行文字识别
return tesseractServer.ocrImage(LanguageTypeEnum.getLanguageByType(language), file);
} catch (Exception e) {
log.error("error:{}", e.getMessage());
return OcrResult.fail(e.getMessage());
}
}
}
启动服务并且测试
http://127.0.0.1:8036/api/ocr/chi_sim 中文引擎识别
http://127.0.0.1:8036/api/ocr/eng 英文引擎识别
到此基于Springboot框架搭建提供Ocr能力的Web服务就完成
html demo扩展
基于html + jquery 搭建的简陋的demo, 访问路径http://127.0.0.1:8036/index.html
index.html文件源码,放到项目resources/static目录下即可
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>OCR测试页面</title>
</head>
<style type="text/css">
#app {
display: flex;
margin: 50px;
height: 1000px;
}
#app div {
padding: 50px;
width: 50%;
border: solid 1px #000;
height: 100%;
}
</style>
<body>
<div id="app">
<div id="left" class="upload-box clear">
<input type="file" id="fileInput">
选择OCR识别使用的语种
<input type="radio" name="language" value="zh_sim" checked="checked"/> 简体中文
<input type="radio" name="language" value="eng"/> 英文
<input id="summit" type="button" value="识别">
</br>
<img id="previewImage" src="" alt="Preview Image" width="100%">
</div>
<div>
<h2>识别结果</h2>
<p>识别时间:<span id="time"></span>毫秒</p>
<p id="resust"></p>
</div>
</div>
<script src="https://cdn.staticfile.org/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript">
const fileInput = document.getElementById('fileInput');
const previewImage = document.getElementById('previewImage');
fileInput.addEventListener('change', function () {
const file = fileInput.files[0]; // 获取选中的文件对象
if (file) {
let language = $('input[name="language"]:checked').val();
uploadOcr(file, language);
const reader = new FileReader();
reader.addEventListener('load', function () {
// 当文件读取完成时触发的事件处理函数
previewImage.src = reader.result;
});
reader.readAsDataURL(file);
}
});
document.getElementById('summit').addEventListener('click', function () {
const file = fileInput.files[0]; // 获取选中的文件对象
let language = $('input[name="language"]:checked').val();
uploadOcr(file, language);
})
function uploadOcr(file, language) {
var formData = new FormData();
formData.append('file', file);
$.ajax({
url: "/api/ocr/" + language, // 上传图片的后端接口地址
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function (response) {
// 上传成功后的处理逻辑
console.log('上传成功' + response);
$("#time").html(response.time);
if (response.success) {
$("#resust").html("");
for (var i = 0; i < response.texts.length; i++) {
$("#resust").append(response.texts[i]).append("<br/>");
}
}
},
error: function (xhr, status, error) {
// 上传失败后的处理逻辑
console.log('上传失败');
}
});
}
</script>
</body>
</html>
项目配套代码
gitee代码地址
创作不易,要是觉得我写的对你有点帮助的话,麻烦在gitee上帮我点下 Star
【SpringBoot框架篇】其它文章如下,后续会继续更新。
- 1.搭建第一个springboot项目
- 2.Thymeleaf模板引擎实战
- 3.优化代码,让代码更简洁高效
- 4.集成jta-atomikos实现分布式事务
- 5.分布式锁的实现方式
- 6.docker部署,并挂载配置文件到宿主机上面
- 7.项目发布到生产环境
- 8.搭建自己的spring-boot-starter
- 9.dubbo入门实战
- 10.API接口限流实战
- 11.Spring Data Jpa实战
- 12.使用druid的monitor工具查看sql执行性能
- 13.使用springboot admin对springboot应用进行监控
- 14.mybatis-plus实战
- 15.使用shiro对web应用进行权限认证
- 16.security整合jwt实现对前后端分离的项目进行权限认证
- 17.使用swagger2生成RESTful风格的接口文档
- 18.使用Netty加websocket实现在线聊天功能
- 19.使用spring-session加redis来实现session共享
- 20.自定义@Configuration配置类启用开关
- 21.对springboot框架编译后的jar文件瘦身
- 22.集成RocketMQ实现消息发布和订阅
- 23.集成smart-doc插件零侵入自动生成RESTful格式API文档
- 24.集成FastDFS实现文件的分布式存储
- 25.集成Minio实现文件的私有化对象存储
- 26.集成spring-boot-starter-validation对接口参数校验
- 27.集成mail实现邮件推送带网页样式的消息
- 28.使用JdbcTemplate操作数据库
- 29.Jpa+vue实现单模型的低代码平台
- 30.使用sharding-jdbc实现读写分离和分库分表
- 31.基于分布式锁或xxx-job实现分布式任务调度
- 32.基于注解+redis实现表单防重复提交
- 33.优雅集成i18n实现国际化信息返回
- 34.使用Spring Retry完成任务的重试
- 35.kafka环境搭建和收发消息
- 36.整合Tess4J搭建提供图片文字识别的Web服务