Mac向けの無料・ローカル完結型OCRツール。⌘⇧4でスクリーンショットを撮る感覚のまま、⌘⇧Oで範囲を選択するだけでOCRしてクリップボードにコピーします。
この図について: サンプルの文章(このリポジトリ用に作成したもの)に対して、このリポジトリのコードを実際に実行して作った図です。範囲選択のオーバーレイ(暗転・選択枠・サイズ表示)と、下段の認識結果は、アプリ本体のコード(
SelectionOverlay.swift/OCRService.swift/TextFormatter.swift)の出力そのままです。通知の表示や貼り付け先は図示用に省略しています。
- 操作は「ショートカット→ドラッグ→離す」だけ。OCR実行ボタンやEnterキーなど、追加操作は一切不要
- 完全ローカル処理。macOS標準の Vision framework (
VNRecognizeTextRequest) でOCRするため、画像・テキストとも外部サーバーへは一切送信されません - 日本語・英語混在テキストに対応。資格試験の問題文のような日英混在文でも認識可能
- APIキー不要・テレメトリなし・アナリティクスなし
- メニューバー常駐型。Dockアイコンを表示せず、バックグラウンドで待機
- Retina / 複数ディスプレイ / 異なる解像度環境に対応
-
速い: 上のサンプル(1240×450px の範囲)で、キャプチャ済み画像の認識から整形までが約0.3秒でした(Apple M4、プロセス起動時間を含む実測)。範囲を離した直後にクリップボードに入ります。
-
通常の文章は実用的: 日本語・英語とも、普通の文章はほぼそのまま読み取れます。日英混在の行も自動判定されます。
-
癖のある部分は貼り付け後に目視確認を: 上のサンプルでは、次の誤りが出ました(実際の出力)。
- 横に並んだ選択肢(
ア TLS イ DNS ウ SMTP エ FTP)は、行が分断されて並びが変わり、エがIになりました - 記号
->が-になりました - コードのインデント(行頭の空白)は、OCRの結果に含まれないため失われます
認識そのものは macOS 標準の Vision framework が行うため、精度は画像の内容(フォント・文字の大きさ・配置)に左右されます。図表や複雑なレイアウトの読み取りには向きません。
- 横に並んだ選択肢(
上のサンプルの認識結果(そのままの出力):
問3 通信の暗号化と、通信相手の認証を同時に行うプロトコルはどれか。
ウ SMTP
ア TLS イ DNS ウ SMTP IFTP
The handshake negotiates a cipher suite before any data is sent.
Release v1.2.0 fixes a crash when launching on macOS 14.
def add(a: int, b: int) - int:
return a + b
- macOS 14.0 (Sonoma) 以降
- Swift 5.9以降のツールチェーン(ビルドする場合。Xcode.appは不要、Command Line Toolsのみで可)
- ビルドの確認は macOS 26 / Swift 6.3 で行っています(
Package.swiftの最低要件は macOS 14)
現時点ではソースからビルドします。
git clone https://github.com/GitSumito/mac-ocr-oss.git
cd mac-ocr-oss
./Scripts/build_app.sh release
open .build/mac-ocr.app常用する場合は .build/mac-ocr.app を /Applications にコピーしてください。
cp -R .build/mac-ocr.app /Applications/
open /Applications/mac-ocr.appログイン時に自動起動させたい場合は、システム設定 → 一般 → ログイン項目 に mac-ocr.app を追加してください。
mac-ocrの動作には 画面収録 (Screen Recording) 権限が必要です。それ以外の権限(アクセシビリティ等)は不要です。
- 初回、
⌘⇧Oを押してOCRを開始しようとすると、権限が無い場合は自動的に:- 画面収録の許可ダイアログ(またはシステム設定への案内)が表示されます
- システム設定の「プライバシーとセキュリティ」→「画面収録」画面が自動的に開きます
- 一覧から mac-ocr を探してオンにしてください
- 権限変更後は mac-ocrを一度再起動してください(TCCの仕様上、権限は次回起動時から反映されます)
手動で設定を開く場合:
システム設定 → プライバシーとセキュリティ → 画面収録
グローバルショートカット (
⌘⇧O) の登録自体は Carbon のRegisterEventHotKeyAPIを使用しており、アクセシビリティ権限は不要です。
- メニューバーのmac-ocrアイコン(虫眼鏡のようなアイコン)が常駐していることを確認
- OCRしたい文字が画面に表示された状態で
⌘⇧Oを押す - 画面が薄暗くなり、範囲選択カーソルに変わるので、OCRしたい範囲をドラッグ
- マウスボタンを離すと、自動的に
- 選択範囲をキャプチャ
- Vision frameworkでOCR
- 結果をクリップボードにコピー
- 「OCRしてクリップボードにコピーしました」という小さな通知を表示
- あとは
⌘Vで貼り付けるだけ
Esc キーで選択をキャンセルできます。
| 操作 | キー |
|---|---|
| OCR範囲選択モード開始 | ⌘ + Shift + O |
| 選択キャンセル | Esc |
メニューバーアイコンからも「OCR開始」「設定...」「終了」を実行できます(「設定...」は、現時点では現在の設定を表示するだけで、変更はできません。カスタマイズは今後の予定です)。
- キャプチャ:
ScreenCaptureKitのSCScreenshotManager.captureImageを使用し、選択範囲のみをディスプレイのバックスケール係数(Retinaでは2倍など)に応じたピクセル解像度で取得 - OCR:
Visionframework のVNRecognizeTextRequestを使用recognitionLevel = .accurate(速度よりも精度を優先。切り抜き画像のため処理時間は問題にならない)recognitionLanguages = ["ja-JP", "en-US"]usesLanguageCorrection = trueautomaticallyDetectsLanguage = true(日英混在の行でも言語を自動判定)
- テキスト整形: 内容の要約・修正は一切行わず、以下の最低限の整形のみ実施
- 各行の行末の空白除去
- 3行以上連続する空行を1行に圧縮
- 前後の余分な空行を除去
- クリップボード:
NSPasteboardにOCR結果のプレーンテキストのみを書き込み(余計な文字列は付加しない)
- OCR対象の画像、認識結果のテキストは 一切外部に送信されません
- クラウドOCR・外部APIは使用していません
- APIキー・アカウント登録は不要です
- テレメトリ・アナリティクスは組み込んでいません
- 通信を行うコードはこのアプリには含まれていません
資格試験の問題、ソースコード、社内情報、個人情報など機密性の高い内容も、すべてローカルのVision frameworkのみで処理されます。
| 状況 | 動作 |
|---|---|
| 画面収録権限がない | トースト表示+システム設定を自動的に開く |
| 選択範囲が小さすぎる | 「選択範囲が小さすぎます」と表示しキャンセル |
| クリックのみ(ドラッグなし) | 何もせず終了(ネイティブのスクリーンショットツールと同じ挙動) |
| 選択範囲に文字が存在しない | 「文字が見つかりませんでした」と表示 |
| OCR処理自体が失敗 | 「OCRに失敗しました」と表示 |
| クリップボードへのコピー失敗 | 「クリップボードへのコピーに失敗しました」と表示 |
Esc でキャンセル |
何も表示せず選択解除(ネイティブツールと同じ挙動) |
| 複数ディスプレイ | 各ディスプレイに個別のオーバーレイを表示し、選択したディスプレイの解像度・スケールで正しくキャプチャ |
このプロジェクトはXcodeプロジェクトを使わず、Swift Package Manager (SPM) のみで構成されています。Command Line Tools for Xcodeがインストールされていれば、フルのXcode.appは不要です。
# 依存確認
swift --version
# デバッグビルド&実行(ターミナルから直接実行。開発中の動作確認向け)
swift runswift run で直接実行した場合、Screen Recording権限は実行しているターミナルアプリ(またはswiftバイナリ)に対して要求される点に注意してください。実運用と同じ権限体験を確認したい場合は、後述の .app ビルドを使用してください。
mac-ocr/
├── Package.swift
├── Sources/mac_ocr/
│ ├── main.swift エントリポイント
│ ├── AppDelegate.swift メニューバー・全体のOCRフロー制御
│ ├── HotkeyManager.swift グローバルショートカット (Carbon RegisterEventHotKey)
│ ├── SelectionOverlay.swift 範囲選択オーバーレイUI
│ ├── CaptureService.swift ScreenCaptureKitによる範囲キャプチャ
│ ├── OCRService.swift Vision frameworkによるOCR
│ ├── TextFormatter.swift OCR結果の最低限の整形
│ ├── ClipboardService.swift クリップボードへの書き込み
│ ├── ToastNotification.swift 非侵襲的な完了通知
│ └── PermissionsHelper.swift 画面収録権限の確認・要求
├── Resources/Info.plist
├── Scripts/build_app.sh .appバンドルのビルドスクリプト
├── docs/images/ README用の図
└── LICENSE
./Scripts/build_app.sh release内部で以下を行っています。
swift build -c releaseでリリースビルドmac-ocr.app/Contents/{MacOS,Resources}を構成し、実行ファイル・Info.plist・AppIcon.icnsを配置codesign --force --deep --sign -でアドホック署名(配布用の正式な署名ではなく、TCC権限をアプリの識別子に安定して紐付けるためのもの)
アプリアイコン(Resources/AppIcon.icns)は外部の画像アセットを使わず、Scripts/generate_icon.swift でAppKitの描画APIから生成しています。デザインを変更したい場合は、そのスクリプトを編集して再実行してください。
swift Scripts/generate_icon.swift
iconutil -c icns Resources/AppIcon.iconset -o Resources/AppIcon.icns生成物: .build/mac-ocr.app
注意: アドホック署名のため、アプリを再ビルドすると署名のハッシュが変わり、画面収録権限の再許可が必要になる場合があります。継続的に開発する場合は、都度システム設定で権限を確認してください。
- 設定画面の本実装(ショートカットのカスタマイズ、認識言語の追加/切り替え、通知のON/OFF)
- 選択範囲を複数ディスプレイにまたがってドラッグできるようにする
- OCR履歴機能(直近N件をメニューバーから再コピー)
- 選択範囲のプレビュー画像を一時保持し、OCR結果と一緒に確認できるUI
- 縦書きテキストへの対応検討
- 正式なDeveloper ID署名 + Notarization対応(配布を前提とする場合)
- 単体テストの追加(Package.swiftへのテストターゲット追加)
