Source code for goojprt.rendering.image_print

# goojprt/rendering/image_print.py
"""Pure image preparation pipeline for thermal printing."""

from goojprt.constants import PAPER_WIDTH_PX
from goojprt.enums import Align


[docs] def prepare_image( img, *, rotate: int = 0, crop: tuple[float, float, float, float] | None = None, scale: float = 1.0, brightness: float = 1.0, contrast: float = 1.0, threshold: int = 128, dither: bool = True, align: str = "center", ): """Prepare a PIL image for thermal printing. Returns a mode-``"1"`` image padded to PAPER_WIDTH_PX. Pipeline: rotate → crop → resize → brightness → contrast → grayscale → threshold/dither → pad to paper width. """ from PIL import Image, ImageEnhance from goojprt.raster import pad_image_to_paper_width img = img.convert("RGB") if rotate: img = img.rotate(rotate, expand=True) if crop is not None: cx, cy, cw, ch = crop w, h = img.size left = int(cx * w) upper = int(cy * h) right = int((cx + cw) * w) lower = int((cy + ch) * h) right = max(right, left + 1) lower = max(lower, upper + 1) img = img.crop((left, upper, right, lower)) w, h = img.size target_w = max(1, int(scale * w)) target_h = max(1, int(h * target_w / w)) img = img.resize((target_w, target_h), Image.Resampling.LANCZOS) if brightness != 1.0: img = ImageEnhance.Brightness(img).enhance(brightness) if contrast != 1.0: img = ImageEnhance.Contrast(img).enhance(contrast) gray = img.convert("L") if dither: bw = gray.convert("1", dither=Image.Dither.FLOYDSTEINBERG) else: bw = gray.point(lambda p: 255 if p > threshold else 0).convert("1", dither=Image.Dither.NONE) _align_map = {"left": Align.LEFT, "center": Align.CENTER, "right": Align.RIGHT} return pad_image_to_paper_width(bw, _align_map.get(align, Align.CENTER))