Source code for pagescan.output
"""PDF output generation."""
from __future__ import annotations
import io
import logging
from pathlib import Path
import cv2
import img2pdf
import numpy as np
from PIL import Image
from pagescan.config import ScanConfig
logger = logging.getLogger(__name__)
[docs]
def save_pdf(image: np.ndarray, output_path: str, config: ScanConfig | None = None) -> None:
"""Save image as a single-page PDF.
Encodes as JPEG and wraps in a PDF sized to the configured page
dimensions (default A4).
"""
if config is None:
config = ScanConfig()
if image.ndim == 2:
pil_img = Image.fromarray(image, mode='L')
else:
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
pil_img = Image.fromarray(rgb)
buf = io.BytesIO()
dpi = config.output_dpi
pil_img.save(buf, format='JPEG', quality=config.jpeg_quality,
optimize=True, dpi=(dpi, dpi))
buf.seek(0)
a4_mm = (img2pdf.mm_to_pt(210), img2pdf.mm_to_pt(297))
layout = img2pdf.get_layout_fun(a4_mm)
pdf_bytes = img2pdf.convert(buf.read(), layout_fun=layout)
Path(output_path).parent.mkdir(parents=True, exist_ok=True)
Path(output_path).write_bytes(pdf_bytes)
[docs]
def save_image(image: np.ndarray, output_path: str) -> None:
"""Save image as JPEG or PNG (inferred from extension)."""
Path(output_path).parent.mkdir(parents=True, exist_ok=True)
cv2.imwrite(output_path, image)