Extract text from images, screenshots, and scanned documents. Supports Chinese, English, mixed Chinese-English, Japanese, and Korean. 100% local operation, privacy-protecting.
Use Cases
- User says "Help me extract the text from this image" or "Convert screenshot to text"
- User says "Recognize the content of this scanned document" or "Extract the information from this business card"
- User says "Extract the table in this photo as text"
- Process scanned pages in a PDF from which text cannot be extracted
Engine Selection (Layered Strategy)
macOS Preferred Path (Zero Installation)
macOS has a built-in Vision Framework, with excellent recognition quality for mixed Chinese-English, and no dependencies need to be installed.
import subprocess, json
def ocr_macos_vision(image_path: str) -> str: """Use macOS Vision Framework for OCR (zero install, best quality on Mac).""" swift_code = f''' import Foundation import Vision
let url = URL(fileURLWithPath: "{image_path}") guard let image = CGImage.from(url: url) else {{ exit(1) }}
let request = VNRecognizeTextRequest() request.recognitionLevel = .accurate request.recognitionLanguages = ["zh-Hans", "zh-Hant", "en-US", "ja", "ko"] request.usesLanguageCorrection = true
let handler = VNImageRequestHandler(cgImage: image) try handler.perform([request])
let results = request.results ?? [] for obs in results {{ if let candidate = obs.topCandidates(1).first {{ print(candidate.string) }} }} ''' # Save and execute Swift script import tempfile, os script_path = tempfile.mktemp(suffix='.swift') with open(script_path, 'w') as f: f.write(swift_code) try: result = subprocess.run( ['swift', script_path], capture_output=True, text=True, timeout=30 ) return result.stdout.strip() finally: os.unlink(script_path)
**使用条件**:macOS 13+,无需安装任何依赖。通过 `nodes` 执行即可。
### 跨平台路径(pip 安装,~50MB)
使用 `rapidocr-onnxruntime`,基于 PaddleOCR v4 模型的 ONNX 推理版本。
```bash
# 首次安装(约 50MB,30 秒内完成)
pip install rapidocr-onnxruntime
from rapidocr_onnxruntime import RapidOCR
engine = RapidOCR()
# 基本识别(自动检测中英文,无需指定语言)
result, elapse = engine("/path/to/image.png")
# result 是列表:[[坐标, 文字, 置信度], ...]
if result:
for line in result:
box, text, confidence = line
print(f"{text} (置信度: {confidence:.2f})")
Execution Method
Via nodes write a Python script to perform OCR.Try macOS Vision first, and fall back to rapidocr when unavailable.
Recommended Execution Script Template
import sys, os, json
image_path = sys.argv[1] if len(sys.argv) > 1 else "/path/to/image.png"
output_path = sys.argv[2] if len(sys.argv) > 2 else None
def ocr_with_best_engine(path: str) -> str:
"""Try macOS Vision first, then rapidocr, then report unavailable."""
import platform
# Tier 1: macOS Vision (zero install)
if platform.system() == "Darwin":
try:
import subprocess
# Quick check: can we run swift?
check = subprocess.run(["swift", "--version"], capture_output=True, timeout=5)
if check.returncode == 0:
return _ocr_macos_vision(path)
except Exception:
pass
# Tier 2: rapidocr-onnxruntime (pip install)
try:
from rapidocr_onnxruntime import RapidOCR
engine = RapidOCR()
result, _ = engine(path)
if result:
return "\n".join(line[1] for line in result)
return "[OCR completed but no text detected]"
except ImportError:
pass
return "[OCR_UNAVAILABLE] No OCR engine found. Install: pip install rapidocr-onnxruntime"
def _ocr_macos_vision(path: str) -> str:
"""macOS Vision Framework OCR via objc bridge."""
try:
import Quartz
from Vision import (
VNRecognizeTextRequest,
VNImageRequestHandler,
)
ci_image = Quartz.CIImage.imageWithContentsOfURL_(
Quartz.NSURL.fileURLWithPath_(path)
)
if ci_image is None:
raise ValueError(f"Cannot load image: {path}")
request = VNRecognizeTextRequest.alloc().init()
request.setRecognitionLevel_(1) # accurate
request.setRecognitionLanguages_(["zh-Hans", "zh-Hant", "en-US", "ja", "ko"])
request.setUsesLanguageCorrection_(True)
handler = VNImageRequestHandler.alloc().initWithCIImage_options_(ci_image, None)
success = handler.performRequests_error_([request], None)
lines = []
for obs in request.results() or []:
candidate = obs.topCandidates_(1)
if candidate:
lines.append(candidate[0].string())
return "\n".join(lines)
except ImportError:
# pyobjc not available, fall through to rapidocr
raise
except Exception as e:
raise RuntimeError(f"macOS Vision OCR failed: {e}")
# Run OCR
text = ocr_with_best_engine(image_path)
# Output
if output_path:
with open(output_path, "w", encoding="utf-8") as f:
f.write(text)
print(f"OCR result saved to: {output_path}")
print(f"Characters extracted: {len(text)}")
else:
print(text)
Batch Processing (All Images in a Directory)
import os, glob
image_dir = "/path/to/scanned_pages"
output_file = "/path/to/extracted_text.md"
images = sorted(glob.glob(os.path.join(image_dir, "*.{png,jpg,jpeg,tiff,bmp}")))
all_text = []
for i, img_path in enumerate(images, 1):
print(f"Processing page {i}/{len(images)}: {os.path.basename(img_path)}")
text = ocr_with_best_engine(img_path)
all_text.append(f"## Page {i}\n\n{text}")
with open(output_file, "w", encoding="utf-8") as f:
f.write("\n\n---\n\n".join(all_text))
print(f"Done: {len(images)} pages -> {output_file}")
Language Support
| Language | rapidocr | macOS Vision | Description |
|---|---|---|---|
| Simplified Chinese | Supported by default | Supported by default | No additional configuration required |
| English | Supported by default | Supported by default | No additional configuration required |
| Mixed Chinese-English | Supported by default | Supported by default | Recognized simultaneously by one model, no switching required |
| Traditional Chinese | Supported by default | Supported by default | Automatically recognized |
| Japanese | Model download required | Supported by default | rapidocr requires additional steps |
| Korean | Model download required | Supported by default | rapidocr requires additional steps |
Security Rules
- 100% local processing: All OCR operations are completed locally, and images are not uploaded to any cloud
- Temporary file cleanup: Delete intermediate temporary files after processing is complete
Output Specifications
- After extraction, display the recognized text (plain text format)
- If there are multiple pages, display them in sections by page number
- If the recognition quality is poor (blurry text/handwriting), inform the user and suggest providing a clearer image
- Keep table content in a structured format as much as possible (use Markdown tables)
- Write the results to a file and inform the user of the path, making it convenient for subsequent use