需求:利用java完成图像文字识别和翻译,实现拍照翻译的功能
可拆分为以下两个小的功能逐一完成:
(1)实现图像文字识别
(2)将识别出来的文字进行翻译。
1.实现图像文字识别
利用Tess4J进行图像文字识别
1.1 为方便集成tess4j的jar包,我们先创建一个maven项目,将所需jar包引入pom.xml
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.4.0</version>
</dependency>
1.2 我们还需要下载语言数据包,进入此仓库https://github.com/tesseract-ocr/tessdata将常用的chi_sim.traineddata 和 eng.traineddata语言包下载下来,存放在一个文件夹中,后面图像文字识别需要用到。我存放在F:\IDEA1\xiaochengxu\src\main\resources\lang
1.3 编写java代码调用Tess4J和语言包进行图像文字识别。
//图片识别 传一个图片和语言(eng/chi_sim)
@PostMapping("/tess4J")
public String Tess4J(@RequestParam("img") MultipartFile img,String language) throws Exception {
// 语言库位置(修改为跟自己上一步下载的语言库文件夹的路径)
String lagnguagePath = "F:\\IDEA1\\xiaochengxu\\src\\main\\resources\\lang";
ITesseract instance = new Tesseract();
//设置训练库的位置
instance.setDatapath(lagnguagePath);
//chi_sim简体中文, eng英文
instance.setLanguage(language); //chi_sim
String result = null;
try {
long startTime = System.currentTimeMillis();
result = instance.doOCR(MultipartFileToFile.multipartFileToFile(img)); //MultipartFileToFile类在下方
long endTime = System.currentTimeMillis();
System.out.println("Time is:" + (endTime - startTime) + " 毫秒");
} catch (TesseractException e) {
e.printStackTrace();
}
System.out.println("result: ");
System.out.println(result);
return result;
}
//MultipartFile转成file
public class MultipartFileToFile {
public static File multipartFileToFile(MultipartFile file) throws Exception {
File toFile = null;
if (file.equals("") || file.getSize() <= 0) {
file = null;
} else {
InputStream ins = null;
ins = file.getInputStream();
toFile = new File(file.getOriginalFilename());
inputStreamToFile(ins, toFile);
ins.close();
}
return toFile;
}
//获取流文件
private static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
1.4 此时我们已经写好了一个接口,将图片和语言(英文eng/中文chi_sim)两个参数传入此接口就能返回图片的文字。配置一下swagger更方便测试。配置swagger教程http://www.gnnu.work/comm/articledetail?articleId=NTY%3D
2.将识别出来的文字进行翻译
接口写好了,这里使用微信小程序作为前端调用此接口。
整体思路就是:在微信小程序中使用wx.chooseImage唤起手机图片系统,上传一张图片,通过js发一个请求,将图片传给第一步写好的后端,后端对图片进行识别,后端将识别后的文字返回给前端,前端再调用翻译的接口将文字翻译即可。
小程序端代码如下:使用了vant https://youzan.github.io/vant-weapp/#/tab
html
<van-tabs active="{{activename}}" bind:change="tabonChange" >
<van-tab title="1.拍照识别" name="1" >
<view style="display:flex;align-items:center;">
<text style="font-weight:700;margin-right:10px">识别成什么语言:</text>
<van-dropdown-menu>
<van-dropdown-item bind:change="changeorclanguage" value="{{ orclanguage }}" options="{{ option1 }}" />
</van-dropdown-menu>
</view>
<button style="" type="primary" disabled="{{disabled1}}" bindtap="uploadImg">{{disabled1?"正在识别中,请稍等":"拍照"}}</button>
<!-- {{orcString}} -->
</van-tab>
<van-tab title="2.翻译" name="2">
<view style="display:flex;align-items:center;">
<text style="font-weight:700;margin-right:10px">翻译成什么语言:</text>
<van-dropdown-menu>
<van-dropdown-item bind:change="changetranslatelanguage" value="{{ translatelanguage }}" options="{{ option2 }}" />
</van-dropdown-menu>
</view>
<button type="primary" bindtap="translate">翻译</button>
<!-- {{translatelanguage}} -->
<van-cell-group>
<van-field
model:value="{{ orcString }}"
placeholder="请输入需要翻译的内容"
type="textarea"
autosize
/>
</van-cell-group>
<!-- <textarea model:value="{{orcString}}" style="margin-top:10px;border:2px solid #ccc;width:100%" /> -->
</van-tab>
<van-tab title="3.结果" name="3">
<view style="display:flex;align-items:center;">
<text style="font-weight:700;margin-right:10px;margin-bootom:1px solid #ccc"> 是否显示原文:</text>
<van-switch checked="{{ showorigin }}" bind:change="changetranslateResutl" size="24px" />
</view>
<view class="adviseCon" wx:for="{{translateResutl}}" wx:for-item="item" wx:for-index="idx" wx:key="idx">
<view >
<view wx:if="{{showorigin}}" style=";margin-bottom:5px" >{{item.src}}</view>
<view style="color:red;margin-bottom:5px" >{{item.dst}}</view>
</view>
</view>
</van-tab>
</van-tabs>
// pages/imgtranslate/imgtranslate.js
Page({
/**
* 页面的初始数据
*/
data: {
orcString:'请输入', //识别图像的结果
activename:'1', //当前的
disabled1:false, //是否禁用第一个按钮
option1: [ //识图的语言
{ text: '中文', value: 'chi_sim' },
{ text: '英文', value: 'eng' },
],
orclanguage:'chi_sim', //识别的目标语言
option2: [ //翻译的语言
{ text: '自动', value: 'auto' },
{ text: '英文', value: 'en' },
{ text: '中文', value: 'zh' },
],
translatelanguage:'auto', //翻译的语言
translateResutl:[] ,//翻译后的结果
showorigin:true, //在翻译后是否显示原文对比
},
//选择识别的语言
changeorclanguage:function(e){
// console.log(e.detail)
this.setData({
orclanguage:e.detail,
})
},
//选择翻译的语言
changetranslatelanguage:function(e){
// console.log(e.detail)
this.setData({
translatelanguage:e.detail,
})
},
changetranslateResutl:function(e){
// console.log(e.detail)
this.setData({
showorigin:e.detail,
})
},
tabonChange:function(e){
console.log(e.detail)
this.setData({
activename:e.detail.name,
})
},
//识别图片
uploadImg:function(){
var _this = this;
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: (res)=> {
_this.setData({
disabled1:true,
})
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var that = _this;
var tempFilePaths = res.tempFilePaths
wx.uploadFile({
url: 'http://127.0.0.1:8080/tess4J?language='+that.data.orclanguage,
filePath: tempFilePaths[0],
name: 'img',
success: function(res){
var data = res.data;
console.log(res)
that.setData({
orcString : res.data,
activename: "2",
disabled1:false,
})
},
fail:function(){
wx.showToast({ title: '服务器错误!', icon: 'none', duration: 2500 })
that.setData({
disabled1:false,
})
}
})
},
fail:function(){
wx.showToast({ title: '是你自己放弃的', icon: 'none', duration: 2500 })
_this.setData({
disabled1:false,
})
}
})
},
translate:function(){
if(this.data.orcString == ""){
wx.showToast({
title: '什么都没有翻译个毛线,下方可以输入',
icon: 'none',
duration: 5500
})
return
}
var that = this;
that.setData({
translateResutl:[],
activename: "3",
})
// console.log(this.data.orcString)
wx.request({
url: 'http://127.0.0.1:8080/bdtranslate',
header: {
"Content-Type": "application/x-www-form-urlencoded"
},
method: "POST",
data: {
word:this.data.orcString,
origin:"auto",
to:this.data.translatelanguage
},
success: function (res) {
console.log(res)
wx.showToast({
title: '翻译成功',
icon: 'none',
duration: 1500
})
that.setData({
translateResutl : res.data.trans_result,
activename: "3",
})
},
fail:function(){
wx.showToast({ title: '服务器错误!', icon: 'none', duration: 1500 })
}
})
},
})