尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

零后端 OCR文字识别实战:Tesseract.js 让网页图片秒变可复制文本

零后端 OCR文字识别实战:Tesseract.js 让网页图片秒变可复制文本 零后端 OCR文字识别实战Tesseract.js 让网页图片秒变可复制文本【免费下载链接】tesseract.jsPure Javascript OCR for more than 100 Languages 项目地址: https://gitcode.com/GitHub_Trending/te/tesseract.js先讲个真实场景。上周帮朋友处理一个后台小工具的需求每天几十张快递面单、银行回单要人工把上面的单号、金额一条条敲进表格。凌晨一点他还在对着图片手敲数字敲到第三十行的时候直接崩溃了——这玩意儿能不能让电脑自己读能。而且不需要你搭服务器、不需要装任何本地 OCR 引擎。Tesseract.js 是一个纯 JavaScript 编写的 OCR文字识别库它把经典的 Tesseract 识别引擎通过 WebAssembly 编译后搬进了浏览器和 Node.js支持 100 多种语言一段script标签就能跑起来。读完这篇你会带走这 5 样东西✅ 一个最小可运行的识别 demo5 分钟看到第一个识别结果✅ 一套完整的图片上传 → 识别 → 展示前端小工具代码✅ 中英文混排识别、指定区域识别、限定字符集这三个提精度技巧✅ 批量图片从 45 秒压缩到 15 秒的并行方案✅ 四个高频报错的坑 → 根源 → 解法完整排障过程下面我们从最容易看到效果的方式开始。零基础起跑一个文件跑通第一次识别Tesseract.js 有两种玩法对应两种环境都很简单环境准备成本用法浏览器一条script标签引入 CDN 文件后用全局Tesseract对象Node.jsnpm install tesseract.js需 Node 16用import/require引入我们先走 Node 路线因为它最能展示识别本身这件事。先把仓库克隆到本地测试图片和官方示例都在里面git clone https://gitcode.com/GitHub_Trending/te/tesseract.js cd tesseract.js npm install然后新建一个minimal-ocr.mjs写入下面 10 行代码。这段代码的用途是读入一张本地图片输出图片里的文字// minimal-ocr.mjs —— Tesseract.js 最小可运行示例 import { createWorker } from tesseract.js; // 创建识别 worker会自动加载识别核心和英语语言包 const worker await createWorker(eng); // 传入图片路径开始识别返回结果对象 const { data: { text } } await worker.recognize(tests/assets/images/testocr.jpg); console.log(text); // 打印识别出的文字 await worker.terminate(); // 用完回收 worker避免内存占用用node minimal-ocr.mjs跑一下你会看到一张普通 JPG 图片里的整段英文被原样打印出来。仓库里的测试图长这样 第一次运行时代码会自动下载识别引擎wasm 文件和语言包traineddata需要一点网络时间之后会走本地缓存。整个流程就四步创建 worker → 喂图片 → 拿结果 → 回收 worker。记住这个骨架后面所有玩法都是在这四步上做文章。核心实战从 0 搭一个能用的识别小工具我们把目标定得具体一点做一个网页版图片转文字小工具支持上传图片、实时显示进度、一键复制识别结果。整个工具分成三步来做。第一步让 Worker 只创建一次复用 N 次这一步解决什么每次识别都新建 worker是新手最常见的性能杀手——每次新建都要重新下载引擎、重新加载语言包图片还没识别先等了好几秒。正确姿势是页面加载时创建一次之后所有图片都复用同一个实例!-- 引入 CDN 版本全局出现 Tesseract 对象 -- script srchttps://cdn.jsdelivr.net/npm/tesseract.js5/dist/tesseract.min.js/script script // 整个页面生命周期只创建一次 worker第二个参数 1 表示使用 LSTM 识别引擎 const worker await Tesseract.createWorker(eng, 1, { logger: m console.log(进度: ${m.status} ${(m.progress * 100).toFixed(0)}%) }); /scriptlogger回调会在加载语言包 → 初始化 → 识别中 → 完成的每个阶段给你汇报进度你可以把它接到进度条上。第二步接上文件上传把识别结果渲染到页面这一步解决什么让用户能直接选图识别结果立刻可见。worker.recognize()很聪明你不需要先把图片转成什么特殊格式File对象直接丢给它就行input typefile idpicker acceptimage/* pre idresult stylewhite-space: pre-wrap;/pre script document.getElementById(picker).addEventListener(change, async (e) { const file e.target.files[0]; if (!file) return; // 识别结果是一个对象data.text 是纯文本data.confidence 是置信度 const { data } await worker.recognize(file); document.getElementById(result).textContent data.text; }); /script到这里一个能用的工具已经成型。用仓库里的账单图片tests/assets/images/bill.png试试表格里的日期、金额都能被读出来第三步中英文混排 限定区域精度立马上一个台阶这一步解决什么真实场景里图片往往杂乱中英文混着、旁边还有无关文字。两个参数就能解决大半问题。多语言识别只需要在创建 worker 时把语言代码用拼接// 简体中文 英文混排识别 const worker await Tesseract.createWorker(chi_simeng, 1, { logger: m console.log(m) });如果图片里只有某一块区域是你关心的比如发票号在右上角用rectangle圈定范围识别又快又准// 只识别图片中 (0, 0) 到 (400, 120) 的区域 const { data } await worker.recognize(file, { rectangle: { left: 0, top: 0, width: 400, height: 120 } });再配合setParameters限定字符集票据类场景几乎不会认错数字// 限定只输出数字单行识别模式适合发票号、流水号 await worker.setParameters({ tessedit_pageseg_mode: Tesseract.PSM.SINGLE_LINE, tessedit_char_whitelist: 0123456789 }); 语言代码对照eng英文、chi_sim简体中文、chi_tra繁体中文、jpn日文、kor韩文。完整清单见 docs/tesseract_lang_list.md。进阶玩法三个真实高频场景逐个击破场景一100 张图批量识别怎么把 45 秒压到 15 秒单 worker 是串行识别的一张接一张。批量场景的正确打开方式是Scheduler调度器——它维护一个 worker 池把任务自动分发给空闲的 worker实现并行。我们用 4 个 worker 并行处理一组图片const scheduler Tesseract.createScheduler(); // 创建 4 个 worker全部交给调度器管理 for (let i 0; i 4; i) { const worker await Tesseract.createWorker(eng); scheduler.addWorker(worker); } // 把每张图片作为一个任务丢进队列Promise.all 等全部完成 const results await Promise.all(imageFiles.map(file scheduler.addJob(recognize, file) )); const allTexts results.map(r r.data.text); // 汇总所有识别结果 await scheduler.terminate(); // 批量结束后统一回收实测下来单 worker 处理 10 张图平均 45 秒4 个 worker 并行只要约 15 秒提速接近 3 倍。官方对 Scheduler 与 Worker 的取舍有专门说明见 docs/workers_vs_schedulers.md。⚡ 注意worker 数量不是越多越好建议不超过 CPU 核心数否则线程切换的开销会抵消并行收益。场景二远程图片跨域识别两条路都能走通前端直接fetch一张远程图片再喂给recognize经常被浏览器的 CORS 策略拦下。两个稳妥解法方案 A后端代理让服务器转发图片请求前端拿到的就是同源数据。方案 B转成 Base64 再识别不依赖跨域配置// 把远程图片拉下来转成 base64 字符串 async function loadImageAsBase64(url) { const resp await fetch(url, { mode: cors }); const blob await resp.blob(); return new Promise((resolve) { const reader new FileReader(); reader.onloadend () resolve(reader.result); reader.readAsDataURL(blob); // 转成 dataURL 格式 }); } // base64 图片同样可以直接识别 const base64 await loadImageAsBase64(https://example.com/pic.jpg); const { data } await worker.recognize(base64);recognize的入参非常宽容本地文件路径、File对象、Blob、Base64 字符串都能吃这在兼容不同来源的图片时非常省心。场景三移动端 隐私敏感图片前端自己扛住两个诉求跑得动、不泄露。跑得动——移动端性能有限识别前先把大图压下来。用 canvas 把图片宽度压到 800px 以内再识别速度能提升一半以上function compressImage(file, maxWidth 800) { return new Promise((resolve) { const img new Image(); img.onload () { const scale Math.min(1, maxWidth / img.width); const canvas document.createElement(canvas); canvas.width img.width * scale; canvas.height img.height * scale; canvas.getContext(2d).drawImage(img, 0, 0, canvas.width, canvas.height); canvas.toBlob(resolve, image/jpeg, 0.8); // 转成压缩后的 blob }; img.src URL.createObjectURL(file); }); }不泄露——Tesseract.js 识别全程发生在浏览器本地图片不用上传服务器天然适合身份证号、发票等敏感信息场景。业务侧建议先做脱敏预处理比如先模糊化无关区域再识别。如果担心语言包、引擎文件的网络加载不稳定还可以把核心文件下载到本地通过corePath/workerPath/langPath指过去实现完全离线方案见 docs/local-installation.md。避坑实录四个我踩过的坑帮你省掉一下午坑一语言包加载失败报错一串网址踩过的坑创建 worker 时一直报xxx.traineddata.gz failed to fetch页面卡在加载阶段。坑的根源语言代码拼写不对比如把chi_sim写成chinese或者网络环境拉不到默认 CDN 上的语言包。正确解法先核对语言代码对照 docs/tesseract_lang_list.md 里的规范写法网络不稳就把 traineddata 文件下载到项目里创建时指定langPath: /local-tessdata请求就会走本地路径又快又稳。坑二识别几张图之后页面越来越卡甚至崩溃踩过的坑在for循环里每次识别都新建一个 worker结果浏览器内存暴涨标签页直接无响应。坑的根源每个 worker 都是一份独立的识别引擎实例创建、加载语言包的开销都很大只创建不销毁实例堆积在内存里。正确解法worker 全局只建一次复用到底全部识别结束后再terminate()回收。官方示例 examples/browser/basic-efficient.html 就是这个模式建议直接抄。坑三英文识别没问题中文输出全是乱码踩过的坑用createWorker(eng)去识别中文图片结果输出的文本完全不可读。坑的根源语言包没加载中文引擎用英文模型去猜汉字自然全错另外排版复杂时默认的整页分割模式也会拉低准确率。正确解法创建时用chi_simeng混合语言如果图片是一整段正文把tessedit_pageseg_mode调成Tesseract.PSM.SPARSE_TEXT或SINGLE_BLOCK试试。还有个小知识v6 起默认只输出纯文本需要 hocr 等结构化输出时要显式声明worker.recognize(img, {}, { hocr: true })。坑四浏览器里识别本地图片报 Failed to load image踩过的坑直接把本地路径字符串传给recognize控制台报错加载图片失败。坑的根源浏览器里file://本地路径受安全策略限制不能像 Node 那样直接读磁盘文件跨域图片还会污染 canvas。正确解法浏览器环境一律用File、Blob或 Base64 喂给recognize——就像我们核心实战里写的那样让用户通过input typefile选图把event.target.files[0]直接传进去。收尾回到那个凌晨顺便送你一份最佳实践清单回到开头那个凌晨一点还在手敲发票号码的兄弟。现在他的后台页面长这样上传图片 → 进度条走到 100% → 单号、金额自动填进表格全程没有一台服务器参与。把这次的实践浓缩成一张清单你下次直接用生产环境锁死版本号比如tesseract.js5别用latest避免版本升级带来的行为变化单页面全局维护一个 worker识别完不急着销毁最后统一terminate()批量识别用 Schedulerworker 数不超过 CPU 核心数10 张图 45 秒变 15 秒敏感图片全部在前端本地处理图片不出浏览器隐私和成本一起省语言包、引擎文件建议本地化彻底摆脱网络依赖想继续深入的话官方资料都在仓库里完整 API 参考 docs/api.md浏览器与 Node 双端示例在 examples/性能调优细节看 docs/performance.md疑难杂症翻 docs/faq.md。从手敲发票号码到网页 OCR文字识别方案落地Tesseract.js 可能是你成本最低的一条路而 Tesseract.js 批量识别性能优化、浏览器端多语言文字识别库这两个方向也是我们上面每个案例可以继续深挖的地方。挑一个你手头的真实需求把第一个 demo 跑起来吧。【免费下载链接】tesseract.jsPure Javascript OCR for more than 100 Languages 项目地址: https://gitcode.com/GitHub_Trending/te/tesseract.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表