deki / utils /pills.py
orasul's picture
Load initial app
6ff22d6
import cv2
import base64
import numpy as np
from typing import Tuple
def preprocess_image(image_bytes: bytes, threshold: int = 1000, scale: float = 0.5, fmt: str = "png") -> Tuple[bytes, str]:
"""
Preprocesses the image by checking its dimensions and downscaling it if needed.
Parameters:
- image_bytes: Raw image bytes.
- threshold: Maximum allowed width or height (in pixels). If either dimension exceeds this,
the image will be downscaled.
- scale: Scale factor to use for resizing if the image is too large.
- fmt: Format for re-encoding the image (e.g., "png" or "jpg").
Returns:
- A tuple (new_image_bytes, new_base64_str) where:
new_image_bytes: The re-encoded image bytes after potential downscaling.
new_base64_str: The base64 string (without header) of the new image bytes.
"""
# Convert raw bytes to a NumPy array then decode with OpenCV
nparr = np.frombuffer(image_bytes, np.uint8)
cv_image = cv2.imdecode(nparr, cv2.IMREAD_UNCHANGED)
if cv_image is None:
raise ValueError("Failed to decode image with OpenCV.")
h, w = cv_image.shape[:2]
# If either dimension is greater than threshold, resize the image.
if h > threshold or w > threshold:
new_w, new_h = int(w * scale), int(h * scale)
cv_image = cv2.resize(cv_image, (new_w, new_h), interpolation=cv2.INTER_AREA)
ret, buf = cv2.imencode(f'.{fmt}', cv_image)
if not ret:
raise ValueError("Failed to re-encode image.")
new_image_bytes = buf.tobytes()
new_base64_str = base64.b64encode(new_image_bytes).decode("utf-8")
return new_image_bytes, new_base64_str