feat(v1): add basic backend and frontend

This commit is contained in:
2026-07-09 00:37:41 +03:30
parent d9eedb3d8e
commit ae240e7ac1
54 changed files with 5829 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
from pathlib import Path
from uuid import uuid4
import cv2
import numpy as np
from django.conf import settings
from .algorithms import ProcessingError, ensure_uint8, image_to_data_url
def session_dir():
path = Path(settings.MEDIA_ROOT) / "sessions"
path.mkdir(parents=True, exist_ok=True)
return path
def save_image_array(image, prefix="image"):
filename = f"sessions/{prefix}-{uuid4().hex}.png"
path = Path(settings.MEDIA_ROOT) / filename
path.parent.mkdir(parents=True, exist_ok=True)
rgb = ensure_uint8(image)
bgr = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
ok, encoded = cv2.imencode(".png", bgr)
if not ok:
raise ProcessingError("Unable to encode image for temporary storage.")
path.write_bytes(encoded.tobytes())
return filename
def load_image_array(relative_path):
path = Path(settings.MEDIA_ROOT) / relative_path
if not path.exists():
raise ProcessingError("Temporary image file is missing or unreadable.")
raw = np.frombuffer(path.read_bytes(), dtype=np.uint8)
image = cv2.imdecode(raw, cv2.IMREAD_COLOR)
if image is None:
raise ProcessingError("Temporary image file is missing or unreadable.")
return cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.uint8)
def delete_relative_file(relative_path):
if not relative_path:
return
path = (Path(settings.MEDIA_ROOT) / relative_path).resolve()
media_root = Path(settings.MEDIA_ROOT).resolve()
if media_root not in path.parents and path != media_root:
return
if path.exists():
path.unlink()
def payload_for_image(image, relative_path):
return {
"image_path": relative_path,
"image_url": f"{settings.MEDIA_URL}{relative_path}",
"image_data": image_to_data_url(image),
}