"""Crop primitive — vendored from backend/app/services/ml/crops.py so the agent is self-contained. Keep in sync if the floor logic changes.""" from PIL import Image MIN_CROP_FRACTION = 0.10 MIN_CROP_PX = 64 def crop_region( img: Image.Image, bbox: tuple[float, float, float, float], *, pad: float = 0.0, min_fraction: float = MIN_CROP_FRACTION, min_px: int = MIN_CROP_PX, ) -> Image.Image | None: """Crop a NORMALIZED bbox (x, y, w, h in [0,1]); None if below the size floor (max of a fraction-of-short-side and an absolute pixel floor).""" iw, ih = img.size x, y, w, h = bbox px, py, pw, ph = x * iw, y * ih, w * iw, h * ih if pad: px -= pw * pad / 2.0 py -= ph * pad / 2.0 pw *= (1.0 + pad) ph *= (1.0 + pad) left = max(0, int(round(px))) top = max(0, int(round(py))) right = min(iw, int(round(px + pw))) bottom = min(ih, int(round(py + ph))) if right <= left or bottom <= top: return None floor = max(min_px, int(min_fraction * min(iw, ih))) if min(right - left, bottom - top) < floor: return None return img.crop((left, top, right, bottom)).convert("RGB")