利用java完成图像文字识别和翻译,实现拍照翻译的功能

2023-11-18

需求:利用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.traineddataeng.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 })
    }
  
  })
  },

 
})

在这里插入图片描述
最后线上体验请微信扫码
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用java完成图像文字识别和翻译,实现拍照翻译的功能 的相关文章

  • 检查用户是否连接到 Facebook,然后检查他是否喜欢某个页面

    有没有什么方法可以检查用户是否在我的外部页面上连接到 Facebook 而不让他们允许我的应用程序之一 同样的问题也适用于 检查用户是否喜欢某个页面 我检查了大约 20 个问题和 3 4 个教程 似乎所有问题都在讨论内部脚本 粉丝页面 应用
  • 单值或常量值时在 x 轴上绘制的样条图 - highchart

    while using the older version of highchart 2 1 6 if a plot had only one value or a series of same values it would plot a
  • 您可以使用 JavaScript 触发自定义 HTML5 表单错误吗?

    如果我有一个像这样的输入
  • 如何在光标下的所有元素上调用 mouseover?

    我有一个网络应用程序 每次单击时都会创建一个点 见下文 当我将鼠标悬停在一堆点上时 我希望光标下的每个点都会触发 mouseover 或 mouseenter 事件 然而 只有一个事件被触发 即堆栈 顶部 的点的事件 当鼠标移动到一堆多个点
  • 如何使用 axios / jest 测试失败的请求

    我创建了一个非常小的应用程序 如果您传递硬币和数量 它可以计算为某些加密货币支付的总价格 我想测试错误 但我总是收到 收到的承诺已解决而不是被拒绝 我相信这是因为如果 url 错误 axios 仍然会解决承诺 我遇到的第二个问题是 我尝试测
  • 如何从表中选择所有偶数 id?

    我想从 MySQL 数据库的表中选择所有甚至帖子 ID 然后显示它们 我还想获取所有带有奇怪 id 的帖子并将它们显示在其他地方 我想使用 PHP 来完成此操作 因为这是我使用的服务器端语言 或者 我是否必须选择所有帖子 然后使用 Java
  • 在 asp.net vb 中通过第一个下拉列表值填充第二个下拉列表

    我在使用 asp net vb 时遇到了一些问题 我想做的是有2个下拉框 第一个下拉菜单将有 1 2 3 例如 第二个下拉菜单将有 A 乙 C 默认情况下 但是 如果选择 1 我希望第二个下拉菜单自动选择 c 我不知道 JavaScript
  • jQuery 的 css() 在应用于滚动事件时滞后

    我正在尝试实现一个简单的 固定标题 表 我知道这在理论上只能用 CSS 来完成 但是当涉及到 OSX Lion 及其消失的滚动条时 它效果不佳 所以我用 jQuery 来做 方法很简单 只有1 5行代码 inbox scroll funct
  • 向对象添加元素

    我需要填充一个 json 文件 现在我有这样的东西 element id 10 quantity 1 我需要添加另一个 元素 我的第一步是使用该 json 将该 json 放入对象类型中cart JSON parse 现在我需要添加新元素
  • 在 JavaScript 中比较表单中的两个数字

    当我尝试比较不同的数字时 数字发生变化 但文本部分保持不变 这只发生在较大 较小的情况下 而不会发生在 NaN 或相等的情况下 这是我的代码 function check var a document getElementById a va
  • 提交前验证表单(比检查空字段更复杂)

    我有一个包含时间输入的表单 具体来说 开放时间和结束时间 当按下提交按钮时 它会转到一个 php 页面 其中这些输入将添加到数据库中 在允许提交表单之前我想检查一些事情 例如 我想确保开始时间早于 小于 结束时间 这是表格 Opens
  • 光滑的轮播缓动示例

    我正在使用 Slick Carousel http kenwheeler github io slick http kenwheeler github io slick 但不知道如何合并不同的幻灯片切换 有人有例子可以分享吗 这是我目前拥有
  • 对象数组 - 在 Vue.js 生态系统中更新对象的正确方法

    我不确定问题到底出在哪里 但我会看看是否有人可以帮助我理解我的代码出了什么问题 我正在利用 Vuex 商店来跟踪某些不断变化的状态 我这样做如下 import Vue from vue import Vuex from vuex Vue u
  • Javascript 选择 onchange='this.form.submit()'

    我有一个带有选择和一些文本输入的表单 我希望在更改选择时提交表单 使用以下方法可以正常工作 onchange this form submit 但是 如果表单还包含提交按钮 则当选择更改时 表单不会提交 我猜有某种冲突 我在这里有什么选择
  • Postman - 如何计算 JSON 响应中特定对象的出现次数

    我是 JSON 和 Postman 的新手 我相信我正在尝试做一些非常简单的事情 我创建了一个 GET 请求 它将获得如下所示的 JSON 响应 在下面的例子中我想得到count响应中所有 IsArchived 属性 这些属性的数量因响应而
  • 常规 JavaScript 可以与 jQuery 混合使用吗?

    例如 我可以采用这个脚本 来自 Mozilla 教程 https developer mozilla org en Canvas tutorial Basic usage
  • 有没有办法防止输入 type=“number” 获得多个点值?

    我只想得到十进制值 如 1 5 0 56 等 但它允许多个点 有什么办法可以预防吗 您可以使用pattern属性
  • 如何根据所需表单输入的值更改 CSS 样式

    我想知道如何编写 javascript 来改变所需的表单元素的样式 如果它们有价值的话就改变它们 我想要做的是当所需的文本字段为空时 在它们周围有一个彩色边框 并在它们有值时删除边框样式 我想做的是编写一个 javascript 函数来检查
  • 如何在 JavaScript 中获取浮点数的小数位?

    我想要的是与 Number prototype toPrecision 几乎相反的 这意味着当我有数字时 它有多少位小数 例如 12 3456 getDecimals 4 对于任何想知道如何更快地完成此操作 无需转换为字符串 的人 这里有一
  • Serviceworker Bug event.respondWith

    我的 serviceworker 的逻辑是 当发生获取事件时 它首先获取包含一些布尔值 而不是 event request url 的端点 并根据我正在调用的值检查该值event respondWith 对于当前的获取事件 我正在提供来自缓

随机推荐

  • 吴恩达深度学习笔记——改善深层神经网络:超参数调整,正则化,最优化(Hyperparameter Tuning)

    深度学习笔记导航 前言 传送门 改善深层神经网络 超参数调整 正则化 最优化 Improving Deep Neural Networks Hyperparameter Tuning Regularization and Optimizat
  • 安装或更新 Android Studio

    在开始用 Jetpack Compose 来编写软件之前 我们需要 1 一台可以联网的电脑 2 安装或更新到 最新版的 Android Studio 3 选择创建 Empty Compose Activity 4 保持版本更新 尝试使用最新
  • Retrofit动态代理+注解+反射简析

    1 定义注解 Get注解 用来定义网络请求类型 Target ElementType METHOD Retention RetentionPolicy RUNTIME public interface Get String value Qu
  • sort()函数的用法说明

    sort 排序是一种简单的快速排序 用于对数组的排序 时间复杂度为n log2 n sort 函数必须是在 cpp 的文件中才能运行 头文件为 include
  • jmeter——BeanShell 预处理程序

    jmeter BeanShell 预处理程序 一 BeanShell 预处理程序描述和作用 二 BeanShell 预处理程序的使用 三 BeanShell 预处理程序的注意事项 四 BeanShell 预处理程序的拓展 一 BeanShe
  • 什么是ADT

    Abstract Data Type 抽象数据类型 是指数据结构作为一个软件组件的实现 ADT的接口用一种类型和该类型上的一组操作来定义 每个操作由它的输入和输出定义 ADT并不会指定数据类型如何实现 这些实现细节对于ADT的用户来说是隐藏
  • php 验证密码大、小写英文字母、数字、特殊字符4选3;且长度大于等于8位

    param password string 明文密码 return array 检测密码合法性 大 小写英文字母 数字 特殊字符 4选3 且长度大于等于8位 function check password legal KaTeX parse
  • pandas把索引变成列

    pandas把索引变成列 只需要使用reset index 这样index就会变成一列变量出现在元数据表中 比如原来的数据表是上面这样 使用reset index 就变成这样 具体reset index 还有一些更细的应用 后续随着学习再继
  • 判断电脑是否插入移动磁盘U盘等并显示结果

    VC 检测判断电脑是否插入移动磁盘U盘等并显示结果 判断手机 U盘 存储卡等设备是否插入到电脑接口中 若检测到某设备 则将设备盘符显示于窗口中 项目源代码 部分代码 程序运行截图
  • 数据库运维之数据库备份的多种方法

    数据库备份 数据库为school 素材如下 1 创建student和score表 CREATE TABLE student id INT 10 NOT NULL UNIQUE PRIMARY KEY name VARCHAR 20 NOT
  • 静态路由及默认路由——基本配置

    拓扑图 原理简述 1 静态路由 是指用户或网络管理员手工配置的路由信息 当网络拓扑结构或链路状态发生改变时 需要网络管理员手工配置静态路由信息 相比较动态路由协议 静态路由无需频繁的交换各自的路由表 配置简单 比较适合小型 简单的网络环境
  • el-switch在按钮内加文字内嵌文字

    产品需求 在按钮内内嵌对应操作文字 原生展示效果 升级展示效果 解决方案 按钮
  • %d, %ld, %lld 区别, %s,%c区别

    相信下面几个表达方式 就能说明问题吧 d int ld long lld long long 在32位编译器上 int long 32bit long long 64bit c是单个字符 也就是用 的 s是字符串 用 的
  • 深入理解SSL VPN

    名词解析 SSL Secure Socket Layer 安全套接字层 TLS Transport Layer Security 传输层安全协议 TLS 1 0是IETF Internet Engineering Task Force In
  • docker-6-docker架构和MySQL容器化的优劣

    1 docker架构 1 开发环境 gt 测试环境 gt 生产环境 2 环境和代码一起放在容器中 解决软件跨环境迁移问题 3 Docker是一个开源的应用容器引擎 4 Docker于2013年基于Go语言实现 5 Docker从17 03版
  • vbox 安装linux64,CentOS 5.8 x64安装VirtualBox-5.0虚拟机

    CentOS 5 8 x64安装VirtualBox 5 0虚拟机 根据自己的环境下载相应的安装包 1 下载并安装for el5 virtualbox虚拟机安装包 安装过程如下 缺依赖包 root lvmtest rpm ivh Virtu
  • html中报错:xxx is not a function

    我今天遇到了一个奇怪的问题 在javascript中写好了一个function 而且之前是可以调用的 例如 在onclick事件中调用 可是新增了一部分代码 也用了onclick调用 但是报错了 不能执行 一直说是xxx is not a
  • JAVA动态生成excel模板;列自定义下拉框赋值

    哈喽 2023大家开工大吉啊 财源滚滚 业务需求 需要生成excel模板 且对部分列设置下拉框 进行动态赋值 效果如下 拿上图举例 针对省这一列 不是填写 而是选择数据 也就是说我们生成excel文件的时候需要把数据填充到下拉框的列中 大体
  • 基本模块的总结

    基本模块的总结 请求模块 urllib库 内置库 urllib request request urlopen 网址或者请求对象 向网址发起请求 request Requqest url 网址 headers 请求头 data 请求参数 创
  • 利用java完成图像文字识别和翻译,实现拍照翻译的功能

    需求 利用java完成图像文字识别和翻译 实现拍照翻译的功能 可拆分为以下两个小的功能逐一完成 1 实现图像文字识别 2 将识别出来的文字进行翻译 1 实现图像文字识别 利用Tess4J进行图像文字识别 1 1 为方便集成tess4j的ja