File size: 4,581 Bytes
4555cad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# 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