Files
meetus/doocus/extractors/image.py
Mariano Gabriel ca8b3a784d doocus first ver
2026-07-05 10:08:42 -03:00

80 lines
2.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
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)