技術 約2分で読めます

@paddlejs-models/ocr はブラウザで動かない(2025年時点)

結論

@paddlejs-models/ocr および関連ライブラリは、2025年12月時点でブラウザ環境では動作しない。Node.js依存のコードが含まれており、Viteやesm.shでのバンドルでもエラーが発生する。

ブラウザでOCRを使いたい場合は Tesseract.js を使うこと。

試したこと

1. @paddlejs-models/ocr(npm)

pnpm add @paddlejs-models/ocr
const ocr = await import('@paddlejs-models/ocr');
await ocr.init();
const result = await ocr.recognize(imageElement);

エラー: ReferenceError: Module is not defined

EmscriptenでコンパイルされたWASMがNode.jsのグローバル変数 Module を参照しており、ブラウザには存在しない。

2. Vite設定での回避

// astro.config.mjs
vite: {
  define: {
    'Module': 'globalThis.Module || {}',
  },
  optimizeDeps: {
    include: ['@paddlejs-models/ocr'],
  },
}

エラー: Invalid define value (must be an entity name or JS literal)

Viteのdefineは式を受け付けない。

3. optimizeDepsからの除外

vite: {
  optimizeDeps: {
    exclude: ['@paddlejs-models/ocr'],
  },
}

結果: 同じ Module is not defined エラー

4. window.Module のポリフィル

<script is:inline>
  window.Module = window.Module || {};
</script>

結果: モジュールのロード時点で既に Module が参照されるため、間に合わない

5. esm.sh CDN

const ocr = await import('https://esm.sh/@paddlejs-models/ocr');

esm.shはnpmパッケージをブラウザ用ESMに変換してくれるCDN。

エラー: 同じ ReferenceError: Module is not defined

esm.shでもNode.js依存のコードは変換できない。

6. @gutenye/ocr-browser

別のラッパーライブラリも試した。

pnpm add @gutenye/ocr-browser onnxruntime-web

問題: open() 関数の型チェックがブラウザで動作せず、すべての入力が [object Object][object HTMLImageElement] に変換されてしまう。

試した入力形式:

  • { data, width, height } オブジェクト
  • HTMLImageElement
  • HTMLCanvasElement
  • ImageData
  • Blob URL
  • Data URL(FileReader)
  • Data URL(canvas.toDataURL)

すべて失敗。

代替案

Tesseract.js(推奨)

pnpm add tesseract.js
import { createWorker } from 'tesseract.js';

const worker = await createWorker('jpn');
const result = await worker.recognize(imageFile);
console.log(result.data.text);
await worker.terminate();
  • 日本語対応
  • ブラウザで問題なく動作
  • 言語データは初回のみCDNからダウンロード(約14MB)

まとめ

PaddleOCRはPython環境では優秀だが、JavaScript/ブラウザ実装は成熟していない。ブラウザでのOCRは素直にTesseract.jsを使うべき。