FluentRead 本地图片 OCR 技术解析:Tesseract.js 资源打包、WASM 加载与语言包管理

发布时间:2026/9/28 2:42:23
FluentRead 本地图片 OCR 技术解析:Tesseract.js 资源打包、WASM 加载与语言包管理 前端AI 应用本地部署【免费下载链接】FluentReadAn open-source browser extension for bilingual translation. 一款开源的浏览器双语翻译插件。项目地址https://gitcode.com/gh_mirrors/fl/FluentRead点击查看免费下载FluentRead 是一款开源的浏览器双语翻译插件其图片翻译、圈选翻译本地 OCR 模式等能力依赖 public/fluent-read-ocr/NOTICE.md 所声明的 Tesseract.js OCR 资产。本文以该 NOTICE 文档为核心结合扩展内真实源码与测试系统讲解 Tesseract.js 6.0.1 及其 core 6.1.2 如何被本地化打包、经 Offscreen 文档与 Web Worker 加载执行以及 OCR 语言包eng / chi_sim / jpn 等如何按需下载、缓存与清除——帮助读者理解这套零 CDN 运行时依赖的本地文字识别基础设施的原理与工程实现。一、NOTICE 文档声明了什么扩展内置的三类 OCR 资产public/fluent-read-ocr/NOTICE.md全文虽短却精确界定了 FluentRead 内置 OCR 资产的组成与来源Tesseract.js 6.0.1Apache-2.0 许可面向浏览器的 Tesseract 封装库提供createWorker等高层 APItesseract.js-core 6.1.2Apache-2.0 许可Tesseract 的 WebAssembly 内核Tesseract 语言数据包eng、chi_sim、jpnMIT 许可traineddata识别模型数据。NOTICE 同时强调了一个关键的工程决策The worker, WebAssembly files, and language data are loaded from this extensions own resources. No OCR code is downloaded from a third-party CDN at runtime.即Worker 脚本、WebAssembly 文件和语言数据一律从扩展自身资源加载运行时绝不从第三方 CDN 下载任何 OCR 代码。这句话决定了整个 OCR 模块的架构取向也解释了public/fluent-read-ocr/目录为何只包含两个文件core/tesseract-core-simd-lstm.wasm.jsSIMD LSTM 版本的 WASM 内核含 asm 化的 .wasm 二进制worker/worker.min.jsTesseract.js 的 worker 脚本。注意目录下只有 SIMD LSTM 一种 core 变体。其原因在 ocrRuntime.ts 的注释中说明——扩展支持的 Chrome/EdgeOffscreen 需 109与 Firefox 140 均支持 WASM SIMD且引擎只使用 LSTM 识别引擎因此不再打包永远不会被选中的非 SIMD 变体缩小扩展体积。二、本地资源如何被定位chrome.runtime.getURL 与扩展资产路径Worker 与 core 之所以能以扩展自身资源身份加载关键在于 ocrRuntime.ts 中的extensionAsset辅助函数function extensionAsset(path: string): string { const getRuntimeUrl chrome.runtime.getURL as (assetPath: string) string; return getRuntimeUrl(/fluent-read-ocr/${path}); }它以chrome.runtime.getURL把public/fluent-read-ocr/下的相对路径解析为chrome-extension://extension-id/fluent-read-ocr/...形式的内置 URL随后传入 Tesseract.js 的createWorker配置createWorker(languages.split(), 1, { workerPath: extensionAsset(worker/worker.min.js), // 本地 Worker 脚本 corePath: extensionAsset(core/tesseract-core-simd-lstm.wasm.js), // 本地 WASM 内核 cachePath: fluent-read-image-ocr, workerBlobURL: false, // 不使用 Blob Worker logger: message { if (message.status recognizing text) onProgress(message.progress, message.userJobId); }, }, OCR_INIT_CONFIG)几个配置项的含义与工程动机workerPath/corePath强制指向扩展内部资源替代 Tesseract.js 默认的 CDN 地址从根上兑现 NOTICE 的零运行时 CDN承诺workerBlobURL: falseTesseract.js 默认会把 worker 包装成 Blob URL而 Offscreen 页面拥有扩展源直接加载本地 worker 可规避 Blob Worker 的 CSP/源限制cachePath: fluent-read-image-ocr指定语言包在 IndexedDB 中的缓存键前缀OCR_INIT_CONFIG {tessedit_load_sublangs: }关闭隐式子语言加载。这是针对 6.1.2 内置 core 的一个已知缺陷规避——该版本在遍历语言 vector 时会追加 CJK 模型声明的竖排子语言导致迭代器失效并误读为「;」由于所需语言已由getOcrLanguages显式传入初始化时关闭隐式子语言即可保留已下载的主模型上游同类问题见 tesseract-ocr/tesseract#4002。测试 imageOcrRuntime.test.ts 直接验证了这条资源链路mock 的chrome.runtime.getURL把路径解析为chrome-extension://test/fluent-read-ocr/worker/worker.min.js与.../core/tesseract-core-simd-lstm.wasm.js并断言createWorker以[jpn, eng]、1单语言模型和上述配置被调用。三、识别在哪里跑Offscreen Document Web Worker 的隔离架构本地 OCR 并不在页面上下文执行而是运行在扩展的隔离环境。从 docs/architecture.md 可以看到整体运行时布局Chrome/Edge MV3 使用原生 Offscreen DocumentFirefox MV2 使用后台页面中的隐藏扩展 iframe两者加载同一个offscreen.html复用同一份 OCR、图片/区域绘制等逻辑。识别调用链大致如下内容脚本或后台发起图片识别请求经由 offscreenAdapter.ts 适配为平台 Offscreen 消息offscreenRuntime.ts 在具备 Canvas/DOM 的隔离文档中完成图片解码、尺寸校验与调用编排ocrRuntime.ts 创建 Tesseract.js Worker真正的识别循环跑在worker.min.js启动的 Web Worker 中ocrWorkerRuntime.ts 负责与引擎无关的 Worker 生命周期与串行任务队列。Offscreen 页面与后台/内容脚本之间只通过类型化消息通信识别产生的位图、Canvas 等临时资源在完成或失败后即被释放见 offscreenRuntime.ts 的模块边界说明。3.1 Worker 复用与串行队列识别不会互相踩踏ocrWorkerRuntime.ts 是整套并发控制的实现核心它保证了同语言 Worker 复用连续识别同语言图片时不会重复创建 Worker、重复初始化语言模型getWorker会比对workerLanguages串行执行所有操作挂在一条尾链operationTail上排队避免一次请求的setParameters/recognize被另一次请求交叉覆盖语言切换先终止旧 Worker等待正在进行的识别结束后才terminate旧 Worker 并创建新语言 Worker切换过程还带所有权代际workerOwnershipGeneration校验防止旧切换恢复后误覆盖新请求安装的实例任务隔离的进度上报通过jobId关联进度只发布当前任务的真实百分比丢弃非法NaN/Infinity、倒退、重复和迟到的进度值。识别时会对 Worker 设置两个 Tesseract 参数worker.setParameters({ tessedit_pageseg_mode: pageSegmentationMode, // 默认 PSM.SPARSE_TEXT11 preserve_interword_spaces: 1, })tessedit_pageseg_mode页面分割模式。普通图片使用PSM.SPARSE_TEXT稀疏文本圈选翻译在空结果时才以PSM.SINGLE_BLOCK6单块重试一次见 ocrRuntime.tspreserve_interword_spaces: 1保留词间空格避免识别文本粘连。以上语义均有 ocrWorkerRuntime.test.ts 的测试覆盖例如复用同语言 Worker 和稀疏文本参数连续识别不重复跨 Worker 初始化第 69-84 行、等待正在进行的识别结束后才终止 Worker 并切换语言第 86-107 行。3.2 取消语义排队取消与执行中取消取消AbortSignal被区分为两种情形ocrWorkerRuntime.ts 对此有精细处理排队中的请求被取消只结束自己的等待不阻塞后续任务尾链继续等待前一任务完成避免后来的请求越过正在进行的 OCR执行中的请求被取消立即释放当前 WorkerterminateCurrentWorker因为其内部状态已不可信同时保证取消不会阻塞串行尾链。两条路径都以AbortErrorname: AbortError提示图片 OCR 请求已取消拒绝调用方且会接住底层迟到的 Promise 拒绝避免遗留未处理 Promise。四、识别前后的图像处理解码、缩放、坐标还原与结果缓存ocrRuntime.ts 在调用 Worker 前后还承担了完整的图像管线4.1 图片解码与预缩放loadOcrImage负责把 data URL 解码为HTMLImageElement并设置15 秒解码超时OCR_IMAGE_DECODE_TIMEOUT_MS 15_000超时、数据无法解码、请求被取消都会给出明确错误并释放src。解码完成后立刻清空source.src释放像素不等远端识别结束第 143-147 行。prepareOcrImage则根据识别场景image整图 /area圈选把图片缩放/加边后绘制到 Canvas 再编码为 PNG整图识别直接使用getOcrImageSize的目标尺寸圈选识别使用getAreaOcrImageSize小图会有界放大并加白边padding以提升低分辨率选区的识别率绘制使用高画质插值imageSmoothingQuality high绘制/编码完成后立即将 Canvas 宽高置 0 释放像素不与 OCR WebAssembly 长期并存第 136-140 行。4.2 坐标映回与结果缓存Tesseract 返回的是归一化/缩放后的 block 结构restoreOcrLineCoordinates会把行级bbox依据sourceWidth/sourceHeight、目标尺寸与 padding 映回原图坐标供翻译绘制层直接在原图上定位。完成的结果会进入一个有界 LRU 缓存completedRecognitionCache上限3 张图 / 12 MBMAX_CACHED_OCR_IMAGES 3、MAX_CACHED_OCR_BYTES 12 * 1024 * 1024超出时淘汰最旧条目返回给调用方的是深拷贝copyOcrLines隔离调用方对缓存内容的修改缓存命中不重放旧进度、不重复创建 Image/Canvas清除语言包后缓存整体清空保证重新识别见 imageOcrRuntime.test.ts 与 第 32-41 行。五、语言包体系八种语言、按需下载与 IndexedDB 缓存NOTICE 声明的三个内置语言包eng、chi_sim、jpn只是默认随扩展声明的最小集合。实际的语言包体系由 ocrLanguages.ts 定义共8 种可下载语言代码语言说明预估大小推荐chi_sim简体中文识别简体中文界面、截图和图片文字约 20 MB✅chi_tra繁體中文识别繁体中文界面、截图和图片文字约 20 MB✅engEnglish识别英文和拉丁字母文字约 11 MB✅spaEspañol识别西班牙语图片文字约 11 MB❌jpn日本語识别日文图片和漫画文字约 16 MB✅kor한국어识别韩语图片文字约 2 MB❌fraFrançais识别法语图片文字约 1 MB❌rusРусский识别俄语图片文字约 5 MB❌数据来自 ocrLanguages.ts 的IMAGE_OCR_LANGUAGE_PACKS约 XX MB 为源码声明的下载体积实际以网络传输为准。5.1 源语言 → 语言包的映射规则getRequiredImageOcrLanguages 把用户选择的源语言映射为需要加载的 Tesseract 语言代码中文按脚本getChineseScript细分简体Hans→chi_sim eng繁体Hant→chi_tra eng明确的英/日/西/韩/法/俄语言 → 对应代码英文只加载eng其余语言加载[代码, eng]英文作为拉丁兜底自动源语言→ 加载推荐组合[chi_sim, chi_tra, eng, jpn]避免默认配置把繁体识别成简体后丢失脚本信息。5.2 语言包下载、缓存与清除语言包不随扩展打包这与 NOTICE 声明的语言数据从扩展自身资源加载并不冲突——NOTICE 针对的是扩展内core与worker两个文件而 traineddata 本身过大且可裁剪因此按需下载。下载与缓存流程在 ocrRuntime.ts 注释中有清晰说明不再把 traineddata 打进扩展Tesseract.js 会从 jsDelivr 按需下载并将解压后的语言包缓存到 Offscreen Document 的 IndexedDB。下载入口downloadImageOcrLanguages→ocrWorkerRuntime.ensureLanguages通过getWorker(normalized)触发 Tesseract.js 的语言包获取流程支持AbortSignal取消客户端侧的语言包准备还有 300 秒超时保护见 client.ts缓存位置IndexedDB 的keyval-store/keyval仓库Tesseract.js 内部 idb-keyval 的默认库键形如fluent-read-image-ocr/lang.traineddata清除入口removeImageOcrLanguages→clearModels→ ocrModelCache.ts 的removeOcrModelFiles按cachePath精确删除指定语言的traineddata键等待事务提交后返回同时清空完成结果缓存只删除明确指定的模型键不清空数据库。下载状态由后台 ocrLanguageRepository.ts 持久化键为fluentReadImageOcrLanguages用户也可以从图片翻译设置中的语言包卡片上手动清除模型释放磁盘占用。六、隐私边界识别本地完成像素不上传本地 OCR 在隐私上有一层重要承诺见 docs/guide/privacy.md 与 docs/guide/image-translation.md文字识别在浏览器本地完成识别出的文字交给所选翻译服务图片像素不会作为文本翻译请求上传。换言之图片数据只在本机Offscreen Worker WASM中流转识别出的文本才可能发送给用户配置的翻译服务语言包首次下载需要网络属于资源获取而非图片上传。圈选翻译还支持优先使用模型识图模型支持图片输入时直接把裁剪后的选区图片交给模型识别这条路径不加载 OCR 语言包、不执行本地识别见 offscreenRuntime.ts。七、WASM 诊断与打包验证core/tesseract-core-simd-lstm.wasm.js这类 vendor WASM 在生产中常产生难以排查的 stderr 输出FluentRead 用 scripts/wasm/diagnostics.js 对内核的打印逻辑做了插桩适配并由 wasmDiagnostics.test.ts 守护将引擎的printErr重定向到扩展的日志通道测试断言插桩后代码包含nb.printErr||fluentReadWasmStderr见 第 63-64 行保留原始严重级别、去除终端颜色把已知无害的 LSTM 旧参数警告如language_model_ngram_on、chop_enable等和分辨率估算提示降为 debug而Error opening data file eng.traineddata、Aborted(out of memory)、Error loading model等真实错误保持可见第 27-48 行。这套诊断管道让内置 WASM 的报错既能被开发/用户看到又不会让已知噪音干扰日志是扩展自带 WASM 资产工程化的一个典型配套。八、小结从 NOTICE 到可运行本地 OCR 的完整链路public/fluent-read-ocr/NOTICE.md虽只有寥寥几行但它所描述的三类资产Tesseract.js 6.0.1、tesseract.js-core 6.1.2、traineddata 语言包和零运行时 CDN原则在源码中被落实为一套完整链路资源定位chrome.runtime.getURL指向扩展内置的worker.min.js与tesseract-core-simd-lstm.wasm.jsocrRuntime.ts隔离执行Offscreen Document Web Worker 承载识别串行队列保证并发安全ocrWorkerRuntime.ts图像管线解码超时、缩放加边、坐标还原、有界结果缓存ocrRuntime.ts语言包管理8 种语言按需下载至 IndexedDB支持定向清除ocrLanguages.ts、ocrModelCache.ts隐私与可观测识别留在本地、像素不上传WASM stderr 经插桩分级输出。相关代码路径汇总NOTICE 声明、OCR 运行时、Worker 运行时、语言包目录、语言包缓存清除、Offscreen 编排、运行时测试、OCR 运行时测试、WASM 诊断测试。读者可按上述路径逐一深入或直接参考 图片翻译指南 体验该能力的实际使用方式。赞分享前端AI 应用本地部署【免费下载链接】FluentReadAn open-source browser extension for bilingual translation. 一款开源的浏览器双语翻译插件。项目地址https://gitcode.com/gh_mirrors/fl/FluentRead点击查看免费下载相关推荐FluentRead 图片翻译完整指南本地 OCR 识别、语言包管理、悬浮入口与隐私边界FluentRead 图片翻译完整指南本地 OCR 识别、语言包管理、悬浮入口与隐私边界 本文以 FluentRead 开源浏览器双语翻译插件的图片翻译功能为前端AI 应用本地部署昇腾GNN算子库ops-gnn一文读懂10大核心算子如何加速图神经网络昇腾GNN算子库ops gnn一文读懂10大核心算子如何加速图神经网络 ops gnn 是昇腾生态下图神经网络GNN专用算子库 基于 Ascend C算子库人工智能深度学习Ascend3个核心技巧彻底解决微信QQ消息撤回烦恼RevokeMsgPatcher实战指南3个核心技巧彻底解决微信QQ消息撤回烦恼RevokeMsgPatcher实战指南 你是否曾因错过重要消息而感到懊恼当对方撤回消息时你是否好奇那条消失的内容桌面应用即时通讯上一篇从0到1开发Fabulous插件VS Code扩展开发完整教程下一篇gh_mirrors/rs/rsschool-app的移动端兼容性测试确保跨设备体验一致创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询