doocus first ver

This commit is contained in:
Mariano Gabriel
2026-07-05 10:08:42 -03:00
parent e214b17c55
commit ca8b3a784d
57 changed files with 4167 additions and 56 deletions

View File

@@ -0,0 +1,79 @@
"""
Image-family extractor: jpg/jpeg, png.
Reads EXIF (including capture date) into metadata, writes a downscaled JPEG
thumbnail, and — when options['ocr'] is set and pytesseract is available — OCRs
the image into content. Without OCR, content is a short placeholder note.
"""
import io
from pathlib import Path
from .base import ExtractionResult
EXTRACTOR_ID = "image/pillow@1"
THUMB_MAX = 640 # longest edge, px
def _exif(img) -> dict:
try:
from PIL.ExifTags import TAGS
except ImportError:
return {}
raw = getattr(img, "_getexif", lambda: None)()
if not raw:
return {}
out = {}
for tag_id, value in raw.items():
name = TAGS.get(tag_id, str(tag_id))
if name in ("DateTime", "DateTimeOriginal", "Make", "Model", "Orientation"):
out[name] = str(value)
return out
def _thumbnail(img) -> bytes:
from PIL import Image # noqa: F401 (ensure Pillow present)
im = img.copy()
im.thumbnail((THUMB_MAX, THUMB_MAX))
if im.mode not in ("RGB", "L"):
im = im.convert("RGB")
buf = io.BytesIO()
im.save(buf, format="JPEG", quality=80)
return buf.getvalue()
def extract(source: Path, options: dict) -> ExtractionResult:
from PIL import Image # lazy
warnings = []
metadata = {}
content = ""
thumb = None
with Image.open(source) as img:
metadata["width"], metadata["height"] = img.size
metadata["mode"] = img.mode
exif = _exif(img)
if exif:
metadata["exif"] = exif
if "DateTimeOriginal" in exif or "DateTime" in exif:
metadata["captured"] = exif.get("DateTimeOriginal", exif.get("DateTime"))
try:
thumb = _thumbnail(img)
except Exception as e:
warnings.append(f"thumbnail failed: {e}")
if options.get("ocr"):
try:
import pytesseract
content = pytesseract.image_to_string(img).strip()
metadata["ocr"] = True
except ImportError:
warnings.append("--ocr requested but pytesseract not installed")
except Exception as e:
warnings.append(f"ocr failed: {e}")
if not content:
content = f"![{source.name}](thumb.jpg)\n\n_Image {metadata.get('width')}×{metadata.get('height')}. Run with --ocr to extract any text._\n"
return ExtractionResult(content=content, metadata=metadata, thumb=thumb,
warnings=warnings, extractor=EXTRACTOR_ID)