Фикс: поддержка WebP через PIL fallback
This commit is contained in:
@@ -3,7 +3,7 @@ import cv2
|
|||||||
import logging
|
import logging
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import requests
|
import requests
|
||||||
from PIL import Image, ImageFilter, ImageEnhance
|
from PIL import Image
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -12,6 +12,26 @@ API_URL = "https://profile.sibcem.ru/SibCemProfile/api/photo-bot/upload/"
|
|||||||
API_KEY = "sibcem_bot_2026_a7f3k9m2x8q1w5e4r6t"
|
API_KEY = "sibcem_bot_2026_a7f3k9m2x8q1w5e4r6t"
|
||||||
|
|
||||||
|
|
||||||
|
def _image_to_cv2(image_bytes: bytes):
|
||||||
|
"""Конвертирует байты изображения в OpenCV матрицу (поддержка webp)."""
|
||||||
|
# Сначала пробуем cv2.imdecode
|
||||||
|
nparr = np.frombuffer(image_bytes, np.uint8)
|
||||||
|
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
|
||||||
|
if img is not None:
|
||||||
|
return img
|
||||||
|
|
||||||
|
# Если не сработало, пробуем через PIL (для webp и других форматов)
|
||||||
|
try:
|
||||||
|
pil_img = Image.open(io.BytesIO(image_bytes))
|
||||||
|
if pil_img.mode != 'RGB':
|
||||||
|
pil_img = pil_img.convert('RGB')
|
||||||
|
img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
|
||||||
|
return img
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Не удалось открыть изображение: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_crop_coordinates(image_bytes: bytes) -> tuple | None:
|
def get_crop_coordinates(image_bytes: bytes) -> tuple | None:
|
||||||
"""
|
"""
|
||||||
Ищет лицо на фото и возвращает координаты квадратного кропа.
|
Ищет лицо на фото и возвращает координаты квадратного кропа.
|
||||||
@@ -19,8 +39,10 @@ def get_crop_coordinates(image_bytes: bytes) -> tuple | None:
|
|||||||
Returns:
|
Returns:
|
||||||
(crop_x1, crop_y1, crop_x2, crop_y2) или None если лицо не найдено.
|
(crop_x1, crop_y1, crop_x2, crop_y2) или None если лицо не найдено.
|
||||||
"""
|
"""
|
||||||
img = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
|
try:
|
||||||
|
img = _image_to_cv2(image_bytes)
|
||||||
if img is None:
|
if img is None:
|
||||||
|
logger.warning("Не удалось декодировать изображение")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
@@ -30,6 +52,7 @@ def get_crop_coordinates(image_bytes: bytes) -> tuple | None:
|
|||||||
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=8, minSize=(50, 50))
|
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=8, minSize=(50, 50))
|
||||||
|
|
||||||
if len(faces) == 0:
|
if len(faces) == 0:
|
||||||
|
logger.warning("Лицо не найдено на фото")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if len(faces) > 1:
|
if len(faces) > 1:
|
||||||
@@ -50,8 +73,13 @@ def get_crop_coordinates(image_bytes: bytes) -> tuple | None:
|
|||||||
crop_x2 = crop_x1 + side
|
crop_x2 = crop_x1 + side
|
||||||
crop_y2 = crop_y1 + side
|
crop_y2 = crop_y1 + side
|
||||||
|
|
||||||
|
logger.info(f"Лицо найдено: ({x},{y},{w},{h}), кроп: ({crop_x1},{crop_y1},{crop_x2},{crop_y2})")
|
||||||
return (crop_x1, crop_y1, crop_x2, crop_y2)
|
return (crop_x1, crop_y1, crop_x2, crop_y2)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Ошибка в get_crop_coordinates: {e}", exc_info=True)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _upload_to_api(image_bytes: bytes, user_id: str, coords: tuple) -> dict:
|
def _upload_to_api(image_bytes: bytes, user_id: str, coords: tuple) -> dict:
|
||||||
"""
|
"""
|
||||||
@@ -121,5 +149,5 @@ def prepare_ad_photo(input_path: str, user_id: str, output_path: str = None, tar
|
|||||||
}
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Ошибка в prepare_ad_photo: {e}")
|
logger.error(f"Ошибка в prepare_ad_photo: {e}", exc_info=True)
|
||||||
return {"success": False, "error": str(e)}
|
return {"success": False, "error": str(e)}
|
||||||
|
|||||||
Reference in New Issue
Block a user