📑
OpenAI OCR × FastAPI × JavaScriptで作るスキャンレス読取 Web アプリを作ってみた
こんにちは、まめです。
最近「紙の伝票をスマホで撮ったら自動でOCRして綺麗な帳票にしてくれる仕組みほしいよね?」という相談を受けることが増えてきました。
そこで今回は OpenAI の Vision OCR を使って、FastAPI × JavaScript で“かざすだけで読み取れる Web アプリ” を作ってみます。
ポイントは以下の通り:
- アプリ側でシャッター不要(ライブカメラ映像をそのまま送信)
- OpenAI の高精度 OCR で手書き伝票もOK
- 取得したテキストを PDF 帳票に埋め込んで出力
- インストール不要の Web アプリで動作
本記事では 最小構成で動く実装 を紹介します。
🔧 1. 全体構成
ユーザーのスマホ / PC カメラ
↓(画像送信)
FastAPI サーバ
↓(OCR)
OpenAI Vision API
↓(解析結果)
FastAPI → PDF 出力
↓
ブラウザへ返却
ポイント:
- フロントは JavaScript のみ
- バックは FastAPI (Python)
- OCR は OpenAI Vision API
- PDF整形は reportlab / fpdf など任意
📸 2. フロントエンド(ブラウザ)
カメラを起動して画像を送信するだけの最短コード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>OCR Web App</title>
</head>
<body>
<video id="camera" autoplay playsinline width="300"></video>
<button id="send">読み取り</button>
<script>
async function startCamera() {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
document.getElementById("camera").srcObject = stream;
}
async function captureAndSend() {
const video = document.getElementById("camera");
const canvas = document.createElement("canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext("2d").drawImage(video, 0, 0);
const blob = await new Promise(resolve => canvas.toBlob(resolve, "image/jpeg"));
const formData = new FormData();
formData.append("file", blob, "capture.jpg");
const res = await fetch("http://localhost:8000/ocr", {
method: "POST",
body: formData
});
const data = await res.json();
alert(data.text);
}
document.getElementById("send").onclick = captureAndSend;
startCamera();
</script>
</body>
</html>
これだけで “シャッターいらずの撮影 & OCR送信” が成立する。
🧠 3. FastAPI(バックエンド)
画像を受け取り → OpenAI OCR → テキスト返却
from fastapi import FastAPI, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from openai import OpenAI
import base64
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
client = OpenAI()
@app.post("/ocr")
async def ocr(file: UploadFile):
img_bytes = await file.read()
b64 = base64.b64encode(img_bytes).decode()
prompt = [
{
"role": "user",
"content": [
{"type": "input_text", "text": "画像の文字を正確に読み取ってください"},
{"type": "input_image", "image_url": f"data:image/jpeg;base64,{b64}"}
]
}
]
res = client.responses.create(
model="gpt-4o-mini",
input=prompt
)
text = res.output_text
return {"text": text}
これで
フロント → FastAPI → OpenAI → テキスト返却 の流れが完了。
🧾 4. OCR結果を PDF 帳票にはめる(オプション)
伝票フォーマットをあらかじめ PDF として持っておき、
OCR結果だけ埋め込む構成も簡単に作れる。
例:fpdf を使った最小実装。
from fpdf import FPDF
def make_pdf(text: str, save_path="output.pdf"):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Helvetica", size=12)
pdf.multi_cell(0, 10, txt=text)
pdf.output(save_path)
OCR後に呼び出すだけ。
📐 5. "かざすだけで読み取る" を実現するポイント
Zenn 読者向けに技術的なポイントもまとめておく:
✔ 高FPSでキャプチャしすぎない
- 1〜2秒間隔程度で撮影することで負荷を抑える
- 読み取れたら API リクエスト停止する仕組みがベスト
✔ 視認性を上げるための補正
- 明るさ調整
- コントラスト補正
- トリミング(紙部分のみ抽出)
※OpenAI OCRは補正なしでも強い。
✔ スマホブラウザで完結
インストール不要なので、現場で導入しやすい。
🚀 6. まとめ|業務で本当に使えるOCR Webアプリが作れる
今回紹介した構成で実現できること:
- 手書き伝票でも高精度なOCR
- カメラをかざすだけで読み取り
- Webアプリのみで動作(スマホアプリ不要)
- PDF帳票まで自動生成できる
実務で「紙 → デジタル化」のニーズは確実に増えています。
FastAPI と OpenAI を組み合わせるだけで、
企業レベルのOCRアプリが個人でも簡単に作れる時代 になりました。
✨ 次回書くならこのへんも深掘りできます
- 文字位置(座標)も抽出して帳票にマッピング
- 伝票レイアウト(枠線付き)を自動生成する
- PDF をメール送信 or データベース保存
- ストリーミングOCR(動画→リアルタイム認識)
Discussion