Spaces:
Runtime error
Runtime error
| # Image processing utilities for dwpose-editor | |
| import numpy as np | |
| import cv2 | |
| from PIL import Image | |
| from .coordinate_system import CoordinateTransformer | |
| from .notifications import notify_success, notify_error, NotificationMessages | |
| def process_uploaded_image(image, target_size=(640, 640)): | |
| """ | |
| アップロードされた画像を処理 | |
| Args: | |
| image: PIL Image or numpy array | |
| target_size: 表示用のターゲットサイズ | |
| Returns: | |
| tuple: (processed_image, original_size, scale_info) | |
| """ | |
| try: | |
| if image is None: | |
| return None, None, None | |
| # PIL ImageをNumPy配列に変換 | |
| if isinstance(image, Image.Image): | |
| original_image = np.array(image) | |
| else: | |
| original_image = image | |
| original_size = (original_image.shape[1], original_image.shape[0]) # (width, height) | |
| # アスペクト比を保持してリサイズ | |
| processed_image, scale_info = resize_with_aspect_ratio( | |
| original_image, target_size | |
| ) | |
| notify_success(NotificationMessages.IMAGE_UPLOADED) | |
| return processed_image, original_size, scale_info | |
| except Exception as e: | |
| notify_error(f"画像処理中にエラーが発生しました: {str(e)}") | |
| return None, None, None | |
| def resize_with_aspect_ratio(image, target_size): | |
| """ | |
| アスペクト比を保持してリサイズ | |
| Args: | |
| image: numpy array | |
| target_size: (width, height) | |
| Returns: | |
| tuple: (resized_image, scale_info) | |
| """ | |
| h, w = image.shape[:2] | |
| target_w, target_h = target_size | |
| # アスペクト比計算 | |
| scale = min(target_w / w, target_h / h) | |
| new_w = int(w * scale) | |
| new_h = int(h * scale) | |
| # リサイズ | |
| resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_AREA) | |
| # パディング(必要に応じて) | |
| if new_w != target_w or new_h != target_h: | |
| # 中央配置でパディング | |
| pad_x = (target_w - new_w) // 2 | |
| pad_y = (target_h - new_h) // 2 | |
| if len(image.shape) == 3: | |
| padded = np.full((target_h, target_w, image.shape[2]), 128, dtype=image.dtype) | |
| else: | |
| padded = np.full((target_h, target_w), 128, dtype=image.dtype) | |
| padded[pad_y:pad_y+new_h, pad_x:pad_x+new_w] = resized | |
| resized = padded | |
| scale_info = { | |
| 'scale': scale, | |
| 'original_size': (w, h), | |
| 'resized_size': (new_w, new_h), | |
| 'final_size': target_size, | |
| 'padding': { | |
| 'x': pad_x if 'pad_x' in locals() else 0, | |
| 'y': pad_y if 'pad_y' in locals() else 0 | |
| } | |
| } | |
| return resized, scale_info | |
| def create_background_canvas(image, canvas_size=(640, 640)): | |
| """ | |
| 背景画像用のCanvasを作成 | |
| Args: | |
| image: 背景画像 | |
| canvas_size: Canvasサイズ | |
| Returns: | |
| numpy array: Canvas用背景画像 | |
| """ | |
| try: | |
| if image is None: | |
| # デフォルト背景 | |
| background = np.full((*canvas_size[::-1], 3), 240, dtype=np.uint8) | |
| return background | |
| # 画像をCanvasサイズに合わせてリサイズ | |
| processed_image, _ = resize_with_aspect_ratio(image, canvas_size) | |
| return processed_image | |
| except Exception as e: | |
| print(f"Background canvas creation error: {e}") | |
| # エラー時はデフォルト背景 | |
| background = np.full((*canvas_size[::-1], 3), 240, dtype=np.uint8) | |
| return background | |
| def image_to_base64(image): | |
| """ | |
| 画像をbase64文字列に変換(Canvas表示用) | |
| Args: | |
| image: numpy array or PIL Image | |
| Returns: | |
| str: base64エンコードされた画像データ | |
| """ | |
| try: | |
| import base64 | |
| import io | |
| if isinstance(image, np.ndarray): | |
| # NumPy配列をPIL Imageに変換 | |
| if image.dtype != np.uint8: | |
| image = (image * 255).astype(np.uint8) | |
| pil_image = Image.fromarray(image) | |
| else: | |
| pil_image = image | |
| # base64に変換 | |
| buffer = io.BytesIO() | |
| pil_image.save(buffer, format='PNG') | |
| img_str = base64.b64encode(buffer.getvalue()).decode() | |
| return f"data:image/png;base64,{img_str}" | |
| except Exception as e: | |
| print(f"Image to base64 conversion error: {e}") | |
| return None |