
Ocr Super Surya
- 541 installs
- 23 repo stars
- Updated August 4, 2026
- aktsmm/agent-skills
ocr-super-surya is a Claude Code skill that defines a named Surya OCR workflow for converting scans, PDFs, and screenshots into text for developers who pipe document images into agent or RAG pipelines.
About
ocr-super-surya is an agent-skills entry from aktsmm/agent-skills that standardizes optical character recognition around the Surya stack when agents ingest scanned pages, PDF exports, or UI screenshots. Instead of improvising one-off OCR prompts, the skill gives a repeatable workflow name and steps agents can invoke during document-to-text automation. Developers reach for ocr-super-surya when building ingestion jobs that must extract searchable text from image-heavy inputs before summarization, indexing, or structured parsing. The repository ships under CC BY-NC-SA 4.0 (2025–2026), so verify license fit before production redistribution of adapted workflows.
- Skill slug ocr-super-surya signals Surya-based OCR for agent-driven document workflows
- Suited to turning images and scanned pages into machine-readable text in dev pipelines
- Pairs with content and knowledge-base builds that need local or scripted OCR steps
- Licensed CC BY-NC-SA 4.0 with explicit AI/ML training restriction in upstream readme
Ocr Super Surya by the numbers
- 541 all-time installs (skills.sh)
- Ranked #145 of 688 Office & Documents skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aktsmm/agent-skills --skill ocr-super-suryaAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 541 |
|---|---|
| repo stars | ★ 23 |
| Security audit | 3 / 3 scanners passed |
| Last updated | August 4, 2026 |
| Repository | aktsmm/agent-skills ↗ |
How do agents OCR PDFs and screenshots reliably?
Give your agent a named OCR workflow around the Surya stack when ingesting scans, PDFs, or screenshots into text pipelines.
Who is it for?
Developers building document-ingestion or RAG pipelines that must turn image-based PDFs and screenshots into machine-readable text.
Skip if: Projects that already use a managed cloud OCR API with strict SLAs and no need for a local Surya-based agent workflow.
When should I use this skill?
The user wants to OCR scans, PDFs, or screenshots with Surya inside an agent or automation pipeline.
What you get
Extracted plain text from scans, PDF pages, or screenshots via a repeatable Surya OCR agent workflow.
- Extracted OCR text
- Named repeatable OCR workflow steps
Files
OCR Super Surya
GPU-optimized OCR using Surya.
When to Use
- OCR, extract text from image, text recognition, 画像から文字
- Extracting text from screenshots, photos, or scanned images
- Processing PDFs with embedded images
- Multi-language document OCR (90+ languages including Japanese)
Features
| Feature | Description |
|---|---|
| Accuracy | 2x better than Tesseract (0.97 vs 0.88) |
| GPU | PyTorch-based, CUDA optimized |
| Languages | 90+ including CJK |
| Layout | Document layout, table recognition |
Quick Start
Installation
# 1. Check GPU
python -c "import torch; print(f'CUDA: {torch.cuda.is_available()}')"
# 2. Install (with CUDA if GPU available)
pip install surya-ocr
# If CUDA=False but you have GPU, reinstall PyTorch:
pip uninstall torch torchvision torchaudio -y
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121Windows + uv 環境(OneDrive配下でのインストール)
OneDrive 配下のフォルダでは uv のハードリンクが失敗するため、以下の手順を使う:
# キャッシュをOneDrive外に設定
$env:UV_CACHE_DIR = "C:\Temp\uv_cache"
# 仮想環境をOneDrive外に作成
uv venv C:\Users\<USERNAME>\ocr_env --python 3.12
# surya-ocrをインストール(link-mode=copy でハードリンクを回避)
uv pip install surya-ocr --python C:\Users\<USERNAME>\ocr_env\Scripts\python.exe --link-mode=copy
# transformers 5.x は非互換 → 4.x を強制
uv pip install "transformers<5.0" --python C:\Users\<USERNAME>\ocr_env\Scripts\python.exe --link-mode=copyUsage
# CLI
python scripts/ocr_helper.py image.png
python scripts/ocr_helper.py document.pdf -l ja en -o result.txt
# Or use surya directly
surya_ocr image.png --output_dir ./resultsPython API
import sys, io
# Windows CP932エンコードエラー対策
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
from PIL import Image
from surya.recognition import RecognitionPredictor
from surya.detection import DetectionPredictor
from surya.foundation import FoundationPredictor
image = Image.open("document.png").convert("RGB")
found_pred = FoundationPredictor()
rec_pred = RecognitionPredictor(found_pred) # v0.13+ : FoundationPredictor必須
det_pred = DetectionPredictor()
# v0.17.x以降: langs引数は廃止 → 渡さないこと
for page in rec_pred([image], det_predictor=det_pred):
for line in page.text_lines:
if line.text.strip():
print(line.text)API変更履歴 (v0.17.x):
>
-RecognitionPredictor(foundation_predictor)-FoundationPredictorが必須引数に変更
-__call__()からlangs引数が削除(自動検出に変更)
GPU Configuration
| Variable | Default | Description |
|---|---|---|
RECOGNITION_BATCH_SIZE | 512 | Reduce for lower VRAM |
DETECTOR_BATCH_SIZE | 36 | Reduce if OOM |
export RECOGNITION_BATCH_SIZE=256
surya_ocr image.pngScripts
| Script | Description |
|---|---|
scripts/ocr_helper.py | Helper with OOM auto-retry, batch support |
Troubleshooting
| エラー | 原因 | 対処 |
|---|---|---|
RecognitionPredictor.__init__() missing 1 required positional argument: 'foundation_predictor' | v0.13+ でAPIが変更 | found_pred = FoundationPredictor() を作成して引数に渡す |
TypeError: __call__() got an unexpected keyword argument 'langs' | v0.17.x で langs 引数廃止 | langs 引数を削除する |
AttributeError: 'SuryaDecoderConfig' object has no attribute 'pad_token_id' | transformers 5.x との非互換 | pip install "transformers<5.0" でダウングレード |
failed to hardlink file ... OneDrive (uv, os error 396) | OneDrive のハードリンク制限 | --link-mode=copy を付けてインストール+UV_CACHE_DIR をOneDrive外に設定 |
UnicodeEncodeError: 'cp932' codec can't encode character | Windows のCP932デフォルトエンコード | sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') を先頭に追加 |
License Note
- Surya: GPL-3.0 (code), commercial license required for >$2M revenue
# Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
## English
Copyright (c) 2025-2026 yamapan (aktsmm)
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0
International License.
You are free to:
- **Share** — copy and redistribute the material in any medium or format
- **Adapt** — remix, transform, and build upon the material
Under the following terms:
- **Attribution** — You must give appropriate credit, provide a link to the
license, and indicate if changes were made. You may do so in any reasonable manner,
but not in any way that suggests the licensor endorses you or your use.
- **NonCommercial** — You may not use the material for commercial purposes.
*(Please contact the author if you wish to use this material for commercial purposes.)*
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological
measures that legally restrict others from doing anything the license permits.
**AI/ML Training Restriction** — Use of this content for AI/ML training, data
mining, or other analytical purposes is prohibited without explicit permission.
Full license text: https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
---
## 日本語
Copyright (c) 2025-2026 yamapan (aktsmm)
この作品はクリエイティブ・コモンズ 表示-非営利-継承 4.0 国際ライセンスの下に提供されています。
あなたは以下の条件に従う限り、自由に:
- **共有** — どのようなメディアやフォーマットでも資料を複製・再配布できます
- **翻案** — 資料をリミックス、変形、および加工することができます
以下の条件に従ってください:
- **表示** — あなたは適切なクレジットを表示し、ライセンスへのリンクを提供し、
変更があったらその旨を示さなければなりません。これらは合理的であればどのような方法で
行っても構いませんが、許諾者があなたやあなたの利用行為を支持していると示唆するような
方法は除きます。
- **非営利** — あなたは営利目的でこの資料を利用してはなりません。
(※商用利用をご希望の場合は、別途ご連絡ください。)
- **継承** — もしあなたがこの資料をリミックス、変形、または加工した場合、
あなたはあなたの貢献部分を元の作品と同じライセンスの下で配布しなければなりません。
追加的な制約は課せません — あなたは、このライセンスが他の者に許諾することを法的に
制限するような法的条項や技術的手段を適用してはなりません。
**AI/MLトレーニング制限** — 本コンテンツをAI/MLモデルのトレーニング、データマイニング、
その他の解析目的での使用は明示的な許可なく禁止されています。
ライセンス全文: https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.ja
---
## Special Permission for Microsoft Employees / Microsoft 社員向け特別許諾
### English
Microsoft Corporation employees are granted permission to use, copy, modify, and
distribute this material for any purpose within the scope of their employment
duties at Microsoft, including internal business use and customer-facing
activities, without the NonCommercial restriction of this license.
This special permission applies only to work performed as part of official
Microsoft business activities.
### 日本語
Microsoft Corporation の社員は、Microsoft での業務の範疇において、本資料を社内業務
および顧客対応を含むあらゆる目的で使用、複製、改変、配布することが許諾されます。
この場合、本ライセンスの「非営利」制限は適用されません。
この特別許諾は、Microsoft の公式な業務活動の一環として行われる作業にのみ適用されます。
---
## Disclaimer / 免責事項
### English
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
### 日本語
本ソフトウェアは「現状のまま」で提供され、明示または黙示を問わず、商品性、
特定目的への適合性、および権利非侵害についての保証を含むがこれに限定されない、
いかなる種類の保証も伴いません。作者または著作権者は、契約行為、不法行為、
またはそれ以外であろうと、ソフトウェアに起因または関連し、あるいはソフトウェアの
使用またはその他の扱いによって生じる一切の請求、損害、その他の責任について
責任を負いません。
#!/usr/bin/env python3
"""
OCR Helper - Surya OCR wrapper for common tasks.
Usage:
from ocr_helper import ocr_image, ocr_pdf
# Single image
text = ocr_image("screenshot.png")
# PDF (all pages)
results = ocr_pdf("document.pdf")
# With verbose logging
text = ocr_image("image.png", verbose=True)
"""
import os
import logging
from pathlib import Path
from typing import Optional
# Configure logging
logger = logging.getLogger("ocr_helper")
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] %(message)s", "%H:%M:%S"))
logger.addHandler(handler)
logger.setLevel(logging.WARNING) # Default: only warnings and errors
def set_verbose(enabled: bool = True):
"""Enable or disable verbose logging."""
logger.setLevel(logging.DEBUG if enabled else logging.WARNING)
# Check GPU availability
def get_device_info() -> dict:
"""Get device information (GPU/CPU)."""
import torch
if torch.cuda.is_available():
return {
"device": "cuda",
"gpu_name": torch.cuda.get_device_name(0),
"vram_gb": torch.cuda.get_device_properties(0).total_memory / (1024**3)
}
return {"device": "cpu", "gpu_name": None, "vram_gb": 0}
def _run_with_oom_retry(func, *args, max_retries: int = 3, **kwargs):
"""
Run a function with automatic OOM retry and batch size reduction.
On CUDA OOM, reduces batch size by half and retries.
"""
import torch
batch_sizes = [
("RECOGNITION_BATCH_SIZE", int(os.environ.get("RECOGNITION_BATCH_SIZE", 512))),
("DETECTOR_BATCH_SIZE", int(os.environ.get("DETECTOR_BATCH_SIZE", 36))),
]
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except (torch.cuda.OutOfMemoryError, RuntimeError) as e:
if "out of memory" not in str(e).lower():
raise
if attempt == max_retries - 1:
logger.error(f"❌ OOM after {max_retries} retries. Consider reducing image size.")
raise
# Reduce batch sizes by half
for env_var, current_size in batch_sizes:
new_size = max(1, current_size // 2)
os.environ[env_var] = str(new_size)
logger.warning(f"⚠️ OOM detected. Reducing {env_var}: {current_size} → {new_size}")
batch_sizes = [(v, s // 2) for v, s in batch_sizes]
# Clear CUDA cache
torch.cuda.empty_cache()
logger.info(f"🔄 Retry {attempt + 2}/{max_retries}...")
def ocr_image(
image_path: str,
output_format: str = "text",
verbose: bool = False,
auto_retry: bool = True
) -> str | dict:
"""
OCR a single image using Surya.
Args:
image_path: Path to the image file
output_format: "text" for plain text, "json" for detailed results
verbose: Enable detailed logging
auto_retry: Automatically retry with smaller batch size on OOM
Note:
Language is auto-detected by Surya. No manual specification needed.
Returns:
Extracted text (str) or detailed results (dict)
"""
if verbose:
set_verbose(True)
from PIL import Image
from surya.recognition import RecognitionPredictor
from surya.detection import DetectionPredictor
from surya.foundation import FoundationPredictor
logger.debug(f"📂 Loading image: {image_path}")
# Load image
image = Image.open(image_path)
logger.debug(f"📐 Image size: {image.size}")
# Initialize predictors
logger.debug("🔧 Initializing predictors...")
foundation_predictor = FoundationPredictor()
recognition_predictor = RecognitionPredictor(foundation_predictor)
detection_predictor = DetectionPredictor()
def _run_ocr():
return recognition_predictor(
[image],
det_predictor=detection_predictor
)
# Run OCR with optional retry
logger.debug("🔍 Running OCR...")
if auto_retry:
predictions = _run_with_oom_retry(_run_ocr)
else:
predictions = _run_ocr()
logger.debug(f"✅ Found {sum(len(p.text_lines) for p in predictions)} text lines")
if output_format == "json":
return {
"text_lines": [
{
"text": line.text,
"confidence": line.confidence,
"bbox": line.bbox
}
for page in predictions
for line in page.text_lines
]
}
# Return plain text
return "\n".join(
line.text
for page in predictions
for line in page.text_lines
)
def ocr_pdf(
pdf_path: str,
dpi: int = 300,
verbose: bool = False,
auto_retry: bool = True
) -> list[str]:
"""
OCR all pages of a PDF.
Args:
pdf_path: Path to the PDF file
dpi: Resolution for PDF to image conversion
verbose: Enable detailed logging
auto_retry: Automatically retry with smaller batch size on OOM
Note:
Language is auto-detected by Surya. No manual specification needed.
Uses pypdfium2 (bundled with surya) - no Poppler required.
Returns:
List of extracted text per page
"""
if verbose:
set_verbose(True)
try:
import pypdfium2 as pdfium
except ImportError:
raise ImportError(
"pypdfium2 is required for PDF processing. "
"It should be included with surya-ocr. "
"Install with: pip install pypdfium2"
)
from PIL import Image
from surya.recognition import RecognitionPredictor
from surya.detection import DetectionPredictor
from surya.foundation import FoundationPredictor
logger.debug(f"📄 Converting PDF to images (dpi={dpi}): {pdf_path}")
# Convert PDF to images using pypdfium2
pdf = pdfium.PdfDocument(pdf_path)
images = []
scale = dpi / 72 # PDF default is 72 DPI
for page_idx in range(len(pdf)):
page = pdf[page_idx]
bitmap = page.render(scale=scale)
pil_image = bitmap.to_pil()
images.append(pil_image)
logger.debug(f"📚 Found {len(images)} pages")
# Initialize predictors
logger.debug("🔧 Initializing predictors...")
foundation_predictor = FoundationPredictor()
recognition_predictor = RecognitionPredictor(foundation_predictor)
detection_predictor = DetectionPredictor()
def _run_ocr():
return recognition_predictor(
images,
det_predictor=detection_predictor
)
# OCR all pages with optional retry
logger.debug("🔍 Running OCR on all pages...")
if auto_retry:
predictions = _run_with_oom_retry(_run_ocr)
else:
predictions = _run_ocr()
# Extract text per page
results = []
for i, page in enumerate(predictions):
page_text = "\n".join(line.text for line in page.text_lines)
results.append(page_text)
logger.debug(f"✅ Page {i+1}: {len(page.text_lines)} lines")
return results
def ocr_batch(
image_paths: list[str],
verbose: bool = False,
auto_retry: bool = True
) -> dict[str, str]:
"""
OCR multiple images in batch (more efficient).
Args:
image_paths: List of image file paths
verbose: Enable detailed logging
auto_retry: Automatically retry with smaller batch size on OOM
Note:
Language is auto-detected by Surya. No manual specification needed.
Returns:
Dictionary mapping file paths to extracted text
"""
if verbose:
set_verbose(True)
from PIL import Image
from surya.recognition import RecognitionPredictor
from surya.detection import DetectionPredictor
from surya.foundation import FoundationPredictor
logger.debug(f"📚 Loading {len(image_paths)} images...")
# Load all images
images = [Image.open(p) for p in image_paths]
# Initialize predictors
logger.debug("🔧 Initializing predictors...")
foundation_predictor = FoundationPredictor()
recognition_predictor = RecognitionPredictor(foundation_predictor)
detection_predictor = DetectionPredictor()
def _run_ocr():
return recognition_predictor(
images,
det_predictor=detection_predictor
)
# Run OCR on all images at once with optional retry
logger.debug("🔍 Running batch OCR...")
if auto_retry:
predictions = _run_with_oom_retry(_run_ocr)
else:
predictions = _run_ocr()
# Map results to file paths
results = {}
for path, page in zip(image_paths, predictions):
results[path] = "\n".join(line.text for line in page.text_lines)
logger.debug(f"✅ {path}: {len(page.text_lines)} lines")
return results
# CLI interface
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="OCR using Surya")
parser.add_argument("input", help="Image or PDF file path")
parser.add_argument("-o", "--output", help="Output file path (optional)")
parser.add_argument("--json", action="store_true", help="Output as JSON")
parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose logging")
parser.add_argument("--no-retry", action="store_true", help="Disable OOM auto-retry")
args = parser.parse_args()
# Enable verbose if requested
if args.verbose:
set_verbose(True)
# Show device info
device_info = get_device_info()
print(f"🖥️ Device: {device_info['device']}", end="")
if device_info['gpu_name']:
print(f" ({device_info['gpu_name']}, {device_info['vram_gb']:.1f}GB)")
else:
print()
# Process input
input_path = Path(args.input)
auto_retry = not args.no_retry
if input_path.suffix.lower() == ".pdf":
print(f"📄 Processing PDF: {input_path}")
results = ocr_pdf(
str(input_path),
verbose=args.verbose,
auto_retry=auto_retry
)
text = "\n\n--- Page Break ---\n\n".join(results)
else:
print(f"🖼️ Processing image: {input_path}")
output_format = "json" if args.json else "text"
text = ocr_image(
str(input_path),
output_format=output_format,
verbose=args.verbose,
auto_retry=auto_retry
)
# Output
if args.output:
with open(args.output, "w", encoding="utf-8") as f:
f.write(text if isinstance(text, str) else str(text))
print(f"✅ Saved to: {args.output}")
else:
print("\n--- OCR Result ---")
print(text)
Related skills
How it compares
Choose ocr-super-surya for agent-native Surya OCR workflows; prefer a cloud OCR API skill when you need vendor-managed scaling and compliance attestations only.
FAQ
What inputs does ocr-super-surya handle?
ocr-super-surya is built for scans, PDFs, and screenshots that must become plain text inside agent workflows, using the Surya OCR stack as the named extraction path before downstream indexing or analysis.
When should developers use ocr-super-surya?
ocr-super-surya fits agent pipelines that repeatedly ingest image-heavy documents and need a consistent Surya-based OCR workflow instead of rewriting extraction instructions per file type.
Is Ocr Super Surya safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.