本文首发地址 https://h89.cn/archives/440.html

一、背景与目标

  • 目标:做一个“拍照翻译”App,在弱网/无网环境下也能工作。离线识别图片中的中文/英文等文字,并把识别结果翻译成中文。
  • 方案:
    • 使用 Google ML Kit Text Recognition v2 实现离线 OCR(中文优先,Latin 回退)。
    • 使用 ML Kit On‑device Translation 实现离线翻译(首次联网下载语言包,下载完成后完全离线)。

二、技术选型与依赖

  • 离线 OCR(中文 + Latin):ML Kit Text Recognition v2。
  • 设备端翻译:ML Kit Translate(On‑device Translation)。
  • 语言识别:ML Kit Language Identification(自动识别待翻译文本源语言)。

工程中关键依赖(app/build.gradle):

dependencies {
    // ML Kit Text Recognition v2(Latin + Chinese)
    implementation 'com.google.mlkit:text-recognition:16.0.1'
    implementation 'com.google.mlkit:text-recognition-chinese:16.0.1'

    // On‑device Translation
    implementation 'com.google.mlkit:translate:17.0.3'

    // Language Identification
    implementation 'com.google.mlkit:language-id:17.0.6'

    // CameraX(相机/拍照)
    implementation 'androidx.camera:camera-core:1.3.4'
    implementation 'androidx.camera:camera-camera2:1.3.4'
    implementation 'androidx.camera:camera-lifecycle:1.3.4'
    implementation 'androidx.camera:camera-view:1.3.4'
}

三、项目结构与关键文件

四、功能实现概览(拍照 + OCR + 翻译)

  • UI:CameraX 预览 + 两个按钮(拍照识别、相册选图)+ 两个文本区域(OCR 结果、翻译结果)。
  • 主流程:
    1. 打开相机 → 拍照保存到缓存 → 使用 ML Kit OCR 识别文字(优先中文,失败回退 Latin)。
    2. 自动语言识别(Language Identification),将识别文本映射到翻译源语言。
    3. 使用设备端翻译,将文本翻译为中文(首次会下载模型,之后可完全离线)。
    4. 识别与翻译结果在页面底部实时显示。

核心实现位于 MainActivity.kt

// 1) 识别(优先中文,回退 Latin)
private fun recognizeText(image: InputImage) {
    val zh = TextRecognition.getClient(ChineseTextRecognizerOptions.Builder().build())
    zh.process(image)
        .addOnSuccessListener { text ->
            val raw = text.text
            if (raw.isNotBlank()) {
                tvOcr.text = raw
                autoDetectAndTranslate(raw)
            } else {
                recognizeLatin(image)
            }
        }
        .addOnFailureListener { recognizeLatin(image) }
}

private fun recognizeLatin(image: InputImage) {
    val latin = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)
    latin.process(image)
        .addOnSuccessListener { text ->
            val raw = text.text
            tvOcr.text = raw
            autoDetectAndTranslate(raw)
        }
        .addOnFailureListener { e -> toast("OCR 失败: ${e.message}") }
}

// 2) 自动语言识别 + 3) 设备端翻译(首次下载模型,之后离线)
private fun autoDetectAndTranslate(text: String) {
    if (text.isBlank()) return
    val identifier = languageIdentifier ?: return
    identifier.identifyLanguage(text)
        .addOnSuccessListener { code ->
            val source = if (code == "und") TranslateLanguage.CHINESE else mapLang(code)
            val target = TranslateLanguage.CHINESE
            setupTranslatorAndTranslate(source, target, text)
        }
        .addOnFailureListener {
            setupTranslatorAndTranslate(TranslateLanguage.ENGLISH, TranslateLanguage.CHINESE, text)
        }
}

private fun setupTranslatorAndTranslate(source: String, target: String, text: String) {
    translator?.close()
    val options = TranslatorOptions.Builder()
        .setSourceLanguage(source)
        .setTargetLanguage(target)
        .build()
    translator = Translation.getClient(options)

    val conditions = DownloadConditions.Builder().build()
    translator!!.downloadModelIfNeeded(conditions)
        .addOnSuccessListener {
            translator!!.translate(text)
                .addOnSuccessListener { out -> tvTrans.text = out }
                .addOnFailureListener { e -> toast("翻译失败: ${e.message}") }
        }
        .addOnFailureListener { e ->
            toast("翻译模型下载失败(需联网一次): ${e.message}")
        }
}

五、为什么能“离线”?

  • OCR:Text Recognition v2 随 App 打包模型,识别完全在设备端执行,不依赖网络。
  • 翻译:On‑device Translation 在首次联网下载语言包后,翻译过程在设备端执行,不上传文本,可离线运行。
  • 自动识别语言:Language Identification 可随 App 打包使用,设备端执行。

六、本地运行与安装

克隆项目

git clone https://github.com/chenjim/mlkit-offline-ocr-translate.git
cd mlkit-offline-ocr-translate

构建与安装

  • 用 Android Studio 直接打开项目,等待依赖同步完成。
  • 连接真机(建议 Android 8.0+),开启 USB 调试。
  • 运行方式:
    • Android Studio 直接 Run 'app'。
    • 或在终端执行(推荐):
      • Windows:.\gradlew.bat installDebug
      • macOS/Linux:./gradlew installDebug
  • 首次使用翻译功能时会自动下载翻译模型,下载完成后即可离线翻译。

七、项目特色与技术亮点

离线优先设计

  • OCR 模型:Text Recognition v2 模型随应用打包,无需网络即可识别文字。
  • 翻译模型:首次联网下载后,完全在设备端执行翻译,保护用户隐私。
  • 语言识别:自动检测文本语言,智能选择翻译源语言。

技术实现细节

  • 中文优先策略:优先使用中文 OCR 模型,识别失败时自动回退到 Latin 模型。
  • 资源管理:合理管理翻译器生命周期,避免内存泄漏。
  • 错误处理:完善的异常处理机制,提供用户友好的错误提示。

项目源码

完整源码已开源至 GitHub:mlkit-offline-ocr-translate

八、常见问题(FAQ)

  • 真能“完全离线”吗?
    • OCR:可以,模型随 App 打包。
    • 翻译:首次需联网下载语言包,下载完成后可完全离线使用。
  • 如何更换翻译目标语言?
    • setupTranslatorAndTranslate() 中将 target 更改为 TranslateLanguage.XXXX 即可。
  • 能否限制仅 Wi‑Fi 下载翻译模型?
    • 可以,将 DownloadConditions.Builder().requireWifi()
  • 模型体积会很大吗?
    • OCR 模型随应用体积增加;翻译模型按需下载并按语言存储在设备端,体积视语言而定。

九、结语

本文以最小可用实现构建了“拍照翻译”离线 App:拍照/选图 → OCR(中文优先)→ 自动识别语言 → 设备端翻译为中文。首次联网下载翻译模型后,即可在无网环境稳定工作。将工程推送到你的 GitHub 仓库(如:github.com/chenjim/mlkit-offline-ocr-translate),即可在博客中引用源码细节,方便读者学习与复现。


本文链接: 离线 OCR + 翻译:做一个无需联网的“拍照翻译”App - https://h89.cn/archives/440.html

版权声明:原创文章 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文链接和本声明。

标签: Camera2, Androidx, google ml, mlkit, text-recognition, translate, offline, ocr

评论已关闭