【OCR】2025年のウェブ実装の限界と知見まとめ
意外と仕事でOCRを使いたい場面はある。
クライアントには
「原稿はテキストデータでください!」
って言ったのに、送られてきたのがPDFだったり、中見たら手書き画像のスキャンだったり、Adobe Acrobat AIは使えないし……。 OCRサービスに出す量でもないし、ウェブOCRサービスに投げると情報流出もヤバいし。
それとは別にOCR処理自体できないのか?みたいな相談があったり。 とはいえうちは別にOCR業者じゃないんで本格的なものはないんだよなあ~。
それウェブで1回実装出来てりゃ困らないだろう。
……と思って色々試した結果、選択肢は思ったより限られていて、用途で使い分けるしかないという結論に至った。この記事では、2025年12月時点での各OCR手法の比較と限界をまとめる。
前提:理想の要件
- サーバーに置きたい(静的サイトでも動く)
- ウェブブラウザ上で完結したい(画像をサーバにアップしたくない)
- 日本語に対応したい
- サーバの転送量を逼迫させたくない(大きめの辞書やWASMを配置したくない)
結論から言うと、全部満たすものは存在しない。 どこかで妥協が必要。
比較表
| ライブラリ | 環境 | 精度 | 日本語 | 段組対応 | セットアップ | コスト | プライバシー |
|---|---|---|---|---|---|---|---|
| Tesseract.js | ブラウザ | △ | ○ | × | 簡単 | 無料 | ◎ |
| Transformers.js | ブラウザ | △〜○ | △(マンガのみ) | × | 中 | 無料 | ◎ |
| PaddleOCR(JS) | ブラウザ(動かない) | - | ○ | - | - | - | - |
| NDLOCR | Docker/サーバー | ◎ | ◎ | △ | 難 | 無料 | ◎ |
| Cloud Vision API | クラウド | ◎ | ◎ | ◎ | 簡単 | 従量課金 | △ |
| AI(GPT-4V等) | クラウド | ○〜◎ | ◎ | ○ | 簡単 | 従量課金 | △ |
以下、それぞれ詳しく見ていく。
ブラウザOCR
Tesseract.js
現状、ブラウザで日本語OCRをやるならこれ一択。
import { createWorker } from 'tesseract.js';
const worker = await createWorker('jpn');
const result = await worker.recognize(imageFile);
console.log(result.data.text);
await worker.terminate();
- 日本語対応
- Web Workerで動くのでUIをブロックしない
- セットアップが簡単(npmでインストールするだけ)
実際に動くデモはLabページに置いてある。
限界
帯域問題がどうしようもない。
初回実行時に言語データ(日本語で約14MB)をCDNからダウンロードする。ブラウザにキャッシュされるので2回目以降は高速だが、初回は重い。
GZIPで圧縮されていても、配信環境によっては回避できない問題になる。自前でホスティングしても14MBは14MB。
精度もサーバーサイドOCRには勝てない。フォントや解像度に依存するし、ノイズや傾きにも弱い。
Transformers.js
Hugging FaceのTransformersをブラウザで動かすライブラリ。OCR用のモデルも対応している。
問題は日本語モデルがない。
| モデル | 日本語 | 備考 |
|---|---|---|
| MGP-STR | × | v3.1で公式対応、英語シーンテキスト向け |
| Florence-2 | △ | OCR機能あり、日本語は要ファインチューニング |
| TrOCR | × | 英語のみ |
| manga-ocr (ONNX) | ○ | マンガ特化、一般文書には不向き |
唯一の日本語対応モデル manga-ocr はマンガのフォント・レイアウトに特化していて、一般的な文書には向かない。
技術的には動くがモデルがないという状況。日本語文書OCRをやりたいなら素直にTesseract.jsを使うべき。
PaddleOCR (JavaScript)
PaddlePaddleのOCRをJavaScriptで動かそうとしたが、2025年12月時点でブラウザでは動かない。
ReferenceError: Module is not defined
EmscriptenでコンパイルされたWASMがNode.jsのグローバル変数 Module を参照しており、ブラウザには存在しない。
試したこと:
@paddlejs-models/ocr(npm)- esm.sh CDN経由
@gutenye/ocr-browser(別ラッパー)
全滅。詳細は別記事に書いた。
JS実装自体が未成熟で、ブラウザ対応は後回しになっている印象。
クラウドAPI・AI
Google Cloud Vision API
精度は間違いない。ほぼ完璧。 段組だろうが縦書きだろうが関係なく正確に読み取る。他のOCRが苦戦するレイアウト問題も、これだけは別格。
でもブログに置く度胸がない。
無料枠はあるが従量課金。記事がバズって大量アクセスが来たら破産する可能性がある。個人プロジェクトで使うにはリスクが高すぎる。
AI(GPT-4V、Claude Vision等)
画像を投げると前後の文脈から上手くテキストを取り出してくれることがある。OCR専用モデルより賢い場面も。
ただし問題が2つ:
- ハルシネーション: 推測しすぎて元にない文章を生成することがある。「読み取り」じゃなくて「創作」になってしまう。
- 情報流出: 機密文書には使えない。データがどこに行くかわからない。
用途を選ぶ。
サーバーOCR
NDLOCR(国立国会図書館OCR)
精度は最強。 日本語文書に特化して開発されているだけあって、他を圧倒する。
問題はセットアップの難しさ。Dockerで動くが、ビルドにかなりハマる。うちの環境での成功手順は別記事にまとめた。
API化のPoC
NDLOCRはDockerで動くので、サーバーに置いてPHPなどでインターフェースを噛ませればAPI化できる。
以下はあくまでPoCレベルのコード例。環境に合わせて書き換えること。動作保証はしない。
<?php
// ndlocr_api.php - 超簡易版、本番では認証・バリデーション必須
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['error' => 'POST only']);
exit;
}
if (!isset($_FILES['image'])) {
http_response_code(400);
echo json_encode(['error' => 'No image uploaded']);
exit;
}
$tmpFile = $_FILES['image']['tmp_name'];
$inputDir = '/path/to/ndlocr/input';
$outputDir = '/path/to/ndlocr/output';
$imageName = uniqid() . '.png';
// 入力ディレクトリに画像を配置
move_uploaded_file($tmpFile, "$inputDir/$imageName");
// NDLOCRコンテナでOCR実行
$cmd = sprintf(
'docker exec ndlocr-container python main.py infer %s %s -s s -p 1',
escapeshellarg("/input/$imageName"),
escapeshellarg("/output")
);
exec($cmd, $output, $returnCode);
if ($returnCode !== 0) {
http_response_code(500);
echo json_encode(['error' => 'OCR failed']);
exit;
}
// 結果のテキストを読み取り(実際のパスは要調整)
$resultPath = "$outputDir/" . pathinfo($imageName, PATHINFO_FILENAME) . ".txt";
$text = file_exists($resultPath) ? file_get_contents($resultPath) : '';
// クリーンアップ
@unlink("$inputDir/$imageName");
@unlink($resultPath);
echo json_encode(['text' => $text]);
本番で使うなら:
- 認証(APIキー等)
- ファイルサイズ・形式のバリデーション
- レートリミット
- エラーハンドリングの強化
- 非同期処理(OCRは時間がかかる)
が必要。
段組・レイアウト認識
ほぼ全てのOCRで弱い。 定番のソリューションがない。
唯一の例外はGoogle Cloud Vision API。段組も縦書きも関係なく読める。ただしコストの問題があるので万能ではない。
NDLOCRでさえ4段組の縦書き書籍は苦手。Layout Parserなどのレイアウト解析ツールを組み合わせても、完璧にはならない。
結局、力技で対処するしかない。PyMuPDFでページを画像化して、ヒストグラム解析で段を切り出す方法を別記事で試した。
レイアウト認識は2025年時点でも未解決問題。何やっても完璧にはならないと思っておいた方がいい。
結論:用途で選ぶ
- 手軽さ・プライバシー優先 → Tesseract.js
- 精度優先 → NDLOCR(サーバー必要)
- お金があってさらに精度が欲しい → Cloud Vision API
- 文脈理解が必要 → AI(ハルシネーションに注意)
ブラウザ完結で高精度な日本語OCRは、2025年時点ではまだ実現できていない。
各ライブラリ・サービスへのリンク
- Tesseract.js - GitHub
- Transformers.js - GitHub
- PaddleOCR - GitHub(JS版は動かないがPython版は優秀)
- NDLOCR - GitHub(国立国会図書館公式)
- Google Cloud Vision API - 公式サイト
- OpenAI GPT-4V - 公式サイト
OCRとは直接関係ないが、ブラウザで動く形態素解析ツールも作ってある。興味があればどうぞ。