Tesseract.js API 详解:createWorker、Scheduler 与 Worker 各方法的完整参考与实现剖析
本篇基于 Tesseract.js 仓库的官方 API 文档(docs/api.md)逐节展开,覆盖 createWorker、Worker 全部方法(recognize、setParameters、reinitialize、detect、terminate、MEMFS 文件操作等)、createScheduler 多 worker 调度、setLogging 日志开关以及 PSM/OEM 常量,并结合 src/createWorker.js、src/createScheduler.js 等源码印证各参数的实际行为。读完后你可以独立完成 worker 生命周期管理、参数调优、多 worker 并发识别与调试排错。
API 总览
从入口文件 src/index.js 可以看到,Tesseract.js 对外导出的核心符号为:
createWorker:创建并初始化一个 worker(本文核心);createScheduler:创建调度器,管理多个 worker 的并发作业队列;setLogging:全局调试日志开关;recognize/detect:已废弃的便捷函数(内部仍是 worker 模式);OEM、PSM、languages:常量枚举,见文末。
一个 Tesseract.js worker 是一个创建并管理 Tesseract 实例的对象:在浏览器中运行于 web worker,在 Node.js 中运行于 worker thread。worker 创建完成后,所有 OCR 作业(job)都通过该 worker 发送。
createWorker(langs, oem, options, config): Promise
createWorker 用于创建一个 Tesseract.js worker。从 src/createWorker.js 的源码签名 createWorker(langs = 'eng', oem = OEM.LSTM_ONLY, _options = {}, config = {}) 可以确认:
- 不传
langs时默认加载英文(eng); - 不传
oem时默认使用OEM.LSTM_ONLY(纯 LSTM 引擎)。
Arguments:
langs:字符串,指定要下载的语言 traineddata;多语言用数组(如['eng', 'chi_sim'])或用+连接的字符串(源码中typeof langs === 'string' ? langs.split('+') : langs可见两种形式都支持,见 src/createWorker.js);oem:枚举,指定 OCR 引擎模式(取值见 OEM);options:自定义选项对象,逐项如下:corePath:指向包含 tesseract.js-core 包中全部以下文件的目录:tesseract-core.wasm.jstesseract-core-simd.wasm.jstesseract-core-lstm.wasm.jstesseract-core-simd-lstm.wasm.js- 网上有些代码把
corePath直接设成某个具体的.js文件,这是强烈不推荐的。为了获得最佳性能和最低网络开销,Tesseract.js 需要能在多个构建版本之间自行选择。
langPath:traineddata 的下载路径,路径末尾不要带/。workerPath:worker 脚本的下载路径。dataPath:traineddata 在 WebAssembly 文件系统(MEMFS)中保存的路径,一般无需修改。cachePath:traineddata 缓存路径,对 Node 更有用;在浏览器中它只是改变 IndexedDB 中的键名。cacheMethod:缓存管理方式,取值为以下之一:write:读缓存并写回(默认方法)readOnly:读缓存但不写回refresh:不读缓存,识别后写回none:不读也不写缓存
legacyCore:设为true可确保下载的代码支持 Legacy 模型(在 LSTM 模型之外)。legacyLang:设为true可确保下载的语言数据支持 Legacy 模型(在 LSTM 模型之外)。workerBlobURL:是否用 Blob URL 加载 worker 脚本,默认true(浏览器端默认值见 src/worker/browser/defaultOptions.js,其中workerPath默认指向与当前包版本一致的 CDN 地址)。gzip:远端 traineddata 是否经过 gzip 压缩,默认true。logger:记录进度的函数,简单示例m => console.log(m)。errorHandler:处理 worker 错误的函数,简单示例err => console.error(err)。
config:初始化之前设置的自定义选项对象。- 该参数用于设置 Tesseract 文档中所说的 “init only”(仅初始化时)参数;
- 大多数 Tesseract 参数可以在 worker 初始化后通过
worker.setParameters或worker.recognize的options参数修改,但少数 “init only” 参数初始化后不可修改,只能通过此参数设置,例如load_system_dawg、load_number_dawg、load_punc_dawg。
路径解析行为:在浏览器环境下,corePath、workerPath、langPath 三个相对路径会被 src/utils/resolvePaths.js 基于 window.location.href 解析为绝对 URL;在 Node 环境下保持原样。因此 langPath 既可以写相对当前页面的路径,也可以写完整 URL。
初始化链路:createWorker 返回的 Promise 在三个内部作业全部完成后才 resolve——load(加载 wasm core)→ loadLanguage(下载语言数据)→ initialize(按 langs/oem/config 初始化引擎),见 src/createWorker.js。此外源码中的 lstmOnlyCore 标志(src/createWorker.js)在 oem 为 DEFAULT/LSTM_ONLY 且未设 legacyCore 时为真,它直接决定了 worker.detect 和切回 Legacy 的 reinitialize 是否可用(下文详述)。
Examples:
const { createWorker } = Tesseract;
const worker = await createWorker('eng', 1, {
langPath: '...',
logger: m => console.log(m),
});
worker.recognize(image, options, output, jobId): Promise
worker.recognize 提供 Tesseract.js 的核心能力:执行 OCR。它能识别 image 中有哪些词、词在图中的位置等。
提示:
image应保证足够高的分辨率。同一张图片在调用recognize前先放大(upscale),往往能得到好得多的结果。
Arguments:
image:支持的输入格式详见 图片格式说明;options:自定义选项对象rectangle:指定要识别的区域对象,应包含top、left、width、height,见下方示例;
output:指定要返回哪些输出格式的对象(默认只返回text);- 其他选项包括
blocks(json)、hocr、tsv等;
- 其他选项包括
jobId:作业 ID(见下文 Scheduler 相关说明)。
输出格式一览:recognize 的默认输出为 output = { text: true }(src/createWorker.js)。worker 内部实际支持的完整输出开关清单见 src/worker-script/constants/defaultOutput.js:
| 字段 | 默认 | 说明 |
|---|---|---|
text |
true |
纯文本 |
blocks |
false |
JSON 结构的分块数据 |
layoutBlocks |
false |
仅版面分析(skipRecognition 时) |
hocr |
false |
HOCR HTML 格式 |
tsv |
false |
TSV 格式 |
box |
false |
训练 box 格式 |
unlv |
false |
UNLV 格式 |
osd |
false |
OSD 文本 |
pdf |
false |
PDF 文件(v4 起取代旧 getPDF 的方式) |
imageColor / imageGrey / imageBinary |
false |
预处理后的彩色/灰度/二值图(base64 PNG) |
debug |
false |
调试信息 |
注意 v6 的变更:除 text 外的所有输出格式默认关闭,如需 hocr 需显式传 worker.recognize(image, {}, { hocr: true })(见 README 的 “Major changes in v6”)。
Output:返回一个 Promise,resolve 为包含 jobId 和 data 属性的对象;data 中包含通过 output 参数指定的所有格式的内容。从结果组装源码 src/worker-script/utils/dump.js 可以看到,data 中还附带 confidence(平均文本置信度)、psm、oem、version 等元信息。
说明:即使未检测到任何文本,
worker.recognize仍会返回输出对象(各输出中只是没有词),不会抛出异常——判定页面为空本身就是一种合法结果。
Examples:
const { createWorker } = Tesseract;
(async () => {
const worker = await createWorker('eng');
const { data: { text } } = await worker.recognize(image);
console.log(text);
})();
带 rectangle 区域识别:
const { createWorker } = Tesseract;
(async () => {
const worker = await createWorker('eng');
const { data: { text } } = await worker.recognize(image, {
rectangle: { top: 0, left: 0, width: 100, height: 100 },
});
console.log(text);
})();
worker.setParameters(params, jobId): Promise
worker.setParameters() 通过 Tesseract API 的 SetVariable() 设置参数,从而改变 Tesseract 的行为。其中 tessedit_char_whitelist 之类的参数非常实用。
Arguments:
params:参数键值对对象;jobId:作业 ID(见上文)。
注意:worker.setParameters 不能用来修改 oem,因为该值在初始化时即已确定(由 createWorker 的参数设置)。worker 已存在时若要改 oem,必须调用 worker.reinitialize。
常用参数:
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
tessedit_pageseg_mode |
enum | PSM.SINGLE_BLOCK |
各模式的定义见下文 PSM 常量表 |
tessedit_char_whitelist |
string | '' |
设置白名单字符后,结果只包含这些字符;当图片内容范围有限时很有用 |
preserve_interword_spaces |
string | '0' |
'0' 或 '1',决定是否保留词间空格 |
user_defined_dpi |
string | '' |
自定义 DPI,用于修复 Warning: Invalid resolution 0 dpi. Using 70 instead. 告警 |
此列表并不完整。由于 Tesseract.js 会把参数透传给 Tesseract 引擎,底层 Tesseract 版本支持的所有参数(除标注为 “init only” 的参数外)原则上都应被 Tesseract.js 支持。
Examples:
(async () => {
await worker.setParameters({
tessedit_char_whitelist: '0123456789',
});
})();
在源码中,setParameters 被封装为一个发送 setParameters 动作的作业(src/createWorker.js),由 worker-script 侧转发给 Tesseract 引擎执行。
worker.reinitialize(langs, oem, config, jobId): Promise
worker.reinitialize() 用不同的 langs 和 oem 重新初始化一个已存在的 worker。
Arguments:
langs:要下载的语言 traineddata,多语言用数组(如['eng', 'chi_sim']);oem:OCR 引擎模式枚举;config:初始化前设置的自定义选项对象(详见createWorker的config说明);jobId:作业 ID。
注意:若要从 LSTM(oem = 1)切换到 Legacy(oem = 0),worker 中必须已经包含运行 Legacy 模型所需的代码。在 createWorker 选项中同时设置 legacyCore: true 与 legacyLang: true 可确保这一点。这一点在源码中有直接对应:src/createWorker.js 中,若当前是 lstmOnlyCore 而新请求的 oem 属于 TESSERACT_ONLY / TESSERACT_LSTM_COMBINED,会直接抛出 'Legacy model requested but code missing.'。另外从 src/createWorker.js 的注释可以推断:reinitialize 只会增量下载尚未加载的语言数据,如果此前只下载了 LSTM-only 语言数据,切到 Legacy 引擎时首次初始化可能失败,之后再重试会下载正确数据。
Examples:
await worker.reinitialize('eng', 1);
worker.detect(image, jobId): Promise
worker.detect 对图片执行 OSD(Orientation and Script Detection,方向与文字方向检测),而不是 OCR。
说明:运行
worker.detect要求 worker 中已加载支持 Tesseract Legacy 的代码和语言数据(默认不启用)。若要用worker.detect,请在createWorker选项中把legacyCore和legacyLang都设为true。
这一限制在源码中是硬校验:当 lstmOnlyCore 为真时,detect 直接抛出 Error('`worker.detect` requires Legacy model, which was not loaded.'),见 src/createWorker.js。
Arguments:
image:图片格式详见 图片格式说明;jobId:作业 ID。
Examples:
const { createWorker } = Tesseract;
(async () => {
const worker = await createWorker('eng', 1, { legacyCore: true, legacyLang: true });
const { data } = await worker.detect(image);
console.log(data);
})();
worker.terminate(jobId): Promise
worker.terminate 终止 worker 并清理资源。从 src/createWorker.js 可以看到,terminate 直接调用平台层(浏览器端为 web worker 的 terminate,Node 端为 worker thread 的终止逻辑,分别位于 src/worker/browser/terminateWorker.js 与 src/worker/node/terminateWorker.js)销毁底层线程,并将内部 worker 引用置空。
(async () => {
await worker.terminate();
})();
实践建议(来自 README):识别多张图片时应只创建一个 worker,对每张图片调用 worker.recognize,最后统一 worker.terminate() 一次,而不是每张图都新建/销毁 worker。
MEMFS 文件操作族:writeText / readText / removeFile / FS
Tesseract.js 在 WebAssembly 中挂载了 MEMFS 文件系统,以下四个方法用于操作其中的文件。它们的底层实现非常直接(src/createWorker.js):
- worker.writeText(path, text, jobId): Promise — 向 MEMFS 指定路径写入文本文件,适用于需要使用“从文件系统读文件”这一特性的功能。对应
FS('writeFile', [path, text])。
(async () => {
await worker.writeText('tmp.txt', 'Hi\nTesseract.js\n');
})();
- worker.readText(path, jobId): Promise — 读取 MEMFS 中指定路径的文本文件,便于检查内容。对应
FS('readFile', [path, { encoding: 'utf8' }])。
(async () => {
const { data } = await worker.readText('tmp.txt');
console.log(data);
})();
- worker.removeFile(path, jobId): Promise — 删除 MEMFS 中的文件,用于释放内存。对应
FS('unlink', [path])。
(async () => {
await worker.removeFile('tmp.txt');
})();
- worker.FS(method, args, jobId): Promise — 通用 FS 函数,可以执行 Emscripten Filesystem API 中的任意方法(完整函数列表参见 Emscripten 官方 Filesystem API 文档)。
(async () => {
await worker.FS('writeFile', ['tmp.txt', 'Hi\nTesseract.js\n']);
// 等价于:
// await worker.writeText('tmp.txt', 'Hi\nTesseract.js\n');
})();
createScheduler(): Scheduler
createScheduler 是工厂函数,创建一个调度器(scheduler)。scheduler 管理一个作业队列(job queue)和一组 worker,让多个 worker 协同工作;当你想通过并行来提升吞吐时很有用。
const { createScheduler } = Tesseract;
const scheduler = createScheduler();
从 src/createScheduler.js 的源码结构看,调度机制为:jobQueue 是一个 FIFO 队列,dequeue 每次从队列头部取出一个作业,分发给第一个空闲(不在 runningWorkers 中)的 worker 执行;作业完成后释放该 worker 并再次触发 dequeue,直到队列排空。addWorker 之后也会立即尝试出队,保证新增 worker 能立刻消化积压作业。
scheduler.addWorker(worker): string
把一个 worker 加入 scheduler 内部的 worker 池。建议一个 worker 只加入一个 scheduler。返回该 worker 的 id。
Examples:
const { createWorker, createScheduler } = Tesseract;
const scheduler = createScheduler();
const worker = await createWorker();
scheduler.addWorker(worker);
scheduler.addJob(action, ...payload): Promise
向作业队列添加一个作业,scheduler 会等待并找到一个空闲 worker 来执行它。
Arguments:
action:要执行的动作,目前仅支持 recognize 与 detect;payload:依据动作而定的任意数量参数。
实现上,作业通过 w[action].apply(this, [...payload, job.id]) 调用对应 worker 的同名方法(src/createScheduler.js),因此 scheduler.addJob('recognize', image, options) 等价于在某个空闲 worker 上执行 worker.recognize(image, options)。另外源码中明确:若尚未添加任何 worker 就调用 addJob,会抛出 'You need to have at least one worker before adding jobs'(src/createScheduler.js)。
Examples:
(async () => {
const { data: { text } } = await scheduler.addJob('recognize', image, options);
const { data } = await scheduler.addJob('detect', image);
})();
scheduler.getQueueLen(): number
返回当前作业队列长度。
scheduler.getNumWorkers(): number
返回已加入 scheduler 的 worker 数量。
scheduler.terminate(): Promise
终止所有已添加的 worker,适合做快速清理。实现上遍历 workers 逐个 terminate() 并清空 jobQueue(src/createScheduler.js)。
Examples:
(async () => {
await scheduler.terminate();
})();
setLogging(logging: boolean)
setLogging 设置全局日志标志:setLogging(true) 后可以看到详细的内部日志,对调试很有用。默认 false。
Arguments:
logging:布尔值,是否输出详细日志。
Examples:
const { setLogging } = Tesseract;
setLogging(true);
源码实现见 src/utils/log.js:模块级布尔量 logging 默认 false,setLogging(_logging) 直接改写它,只有打开后 log(...) 才会调用 console.log。createWorker 内部对每个作业的 start/complete 都会打日志(如 Start <jobId>, action=recognize),因此打开该开关是排查“作业卡在哪一步”的最直接手段。
已废弃函数:recognize() 与 detect()
警告:以下两个顶层函数已废弃,应替换为上文的
worker.recognize与worker.detect。
- recognize(image, langs, options): Promise — 行为与
worker.recognize相同,区别在于每次调用都会新建、加载并销毁一个 worker,开销显著更高; - detect(image, options): Promise — 行为与
worker.detect相同,同样每次调用都会创建并销毁 worker。
从 src/Tesseract.js 的源码可以确认其等价流程:recognize 内部执行 createWorker(langs, 1, options) → worker.recognize(image),并在 finally 中 worker.terminate();detect 则固定以 createWorker('osd', 0, options)(即 OSD 语言 + Legacy 引擎)方式构造 worker 再执行 worker.detect。除非只是一次性脚本,否则都应改用可复用的 worker。
PSM 与 OEM 常量
这两个枚举以字符串/数字常量形式从 src/constants/PSM.js 和 src/constants/OEM.js 导出,并随 Tesseract.PSM、Tesseract.OEM 对外暴露。
PSM(Page Segmentation Mode,页面分割模式),完整取值表:
| 常量 | 值 | 常量 | 值 |
|---|---|---|---|
OSD_ONLY |
'0' |
SINGLE_BLOCK_VERT_TEXT |
'5' |
AUTO_OSD |
'1' |
SINGLE_BLOCK |
'6' |
AUTO_ONLY |
'2' |
SINGLE_LINE |
'7' |
AUTO |
'3' |
SINGLE_WORD |
'8' |
SINGLE_COLUMN |
'4' |
CIRCLE_WORD |
'9' |
SINGLE_CHAR |
'10' |
||
SPARSE_TEXT |
'11' |
||
SPARSE_TEXT_OSD |
'12' |
||
RAW_LINE |
'13' |
其中 SINGLE_BLOCK('6')是 tessedit_pageseg_mode 的默认值,与上文 setParameters 参数表一致。
OEM(OCR Engine Mode,OCR 引擎模式):
| 常量 | 值 | 含义 |
|---|---|---|
TESSERACT_ONLY |
0 |
仅 Legacy 引擎 |
LSTM_ONLY |
1 |
仅 LSTM 引擎(默认) |
TESSERACT_LSTM_COMBINED |
2 |
Legacy + LSTM 组合 |
DEFAULT |
3 |
由 Tesseract 决定 |
源码注释(src/constants/OEM.js)明确 “By default tesseract.js uses LSTM_ONLY mode”。由于默认下载的是 LSTM-only 构建,若需要 0 或 2 模式或 OSD 功能,需按前文所述设置 legacyCore / legacyLang。
小结与快速对照
- 常规流程:
createWorker(langs, oem, options)一次 → 多次worker.recognize(image, options, output)→ 最后一次worker.terminate(); - 调参:初始化前用
config(仅限 init-only 参数),初始化后用worker.setParameters(params);oem变更走worker.reinitialize; - OSD/方向检测:
worker.detect,前提是 worker 已加载 Legacy 支持; - 吞吐优化:
createScheduler+ 多个addWorker+addJob('recognize', ...)自动分派空闲 worker; - 调试:
setLogging(true)观察作业级日志;MEMFS 四个文件方法用于文件系统交互场景。
各方法完整签名与参数表以仓库 docs/api.md 为准,行为细节可对照 src/createWorker.js、src/createScheduler.js、src/Tesseract.js 与 src/worker-script/utils/dump.js 阅读验证。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00