Spaces:
Running
on
Zero
Running
on
Zero
Fixed the base64 to PIL image function
Browse files- gradio_app.py +21 -1
- hy3dshape/hy3dshape/preprocessors.py +40 -4
gradio_app.py
CHANGED
@@ -141,8 +141,28 @@ def base64_to_pil_image(base64_string: str) -> Image.Image:
|
|
141 |
if base64_string.startswith('data:image'):
|
142 |
base64_string = base64_string.split(',')[1]
|
143 |
|
144 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
image = Image.open(io.BytesIO(image_data))
|
|
|
|
|
|
|
|
|
146 |
return image
|
147 |
except Exception as e:
|
148 |
raise HTTPException(status_code=400, detail=f"Invalid image data: {str(e)}")
|
|
|
141 |
if base64_string.startswith('data:image'):
|
142 |
base64_string = base64_string.split(',')[1]
|
143 |
|
144 |
+
# Ensure we have valid base64 data
|
145 |
+
# Add padding if necessary
|
146 |
+
missing_padding = len(base64_string) % 4
|
147 |
+
if missing_padding:
|
148 |
+
base64_string += '=' * (4 - missing_padding)
|
149 |
+
|
150 |
+
# Decode base64 data
|
151 |
+
try:
|
152 |
+
image_data = base64.b64decode(base64_string)
|
153 |
+
except Exception as e:
|
154 |
+
raise ValueError(f"Failed to decode base64 string: {str(e)}")
|
155 |
+
|
156 |
+
# Ensure we have valid image data
|
157 |
+
if not image_data or len(image_data) == 0:
|
158 |
+
raise ValueError("Empty image data after base64 decoding")
|
159 |
+
|
160 |
+
# Open as PIL Image
|
161 |
image = Image.open(io.BytesIO(image_data))
|
162 |
+
|
163 |
+
# Ensure consistent format - convert to RGBA
|
164 |
+
image = image.convert("RGBA")
|
165 |
+
|
166 |
return image
|
167 |
except Exception as e:
|
168 |
raise HTTPException(status_code=400, detail=f"Invalid image data: {str(e)}")
|
hy3dshape/hy3dshape/preprocessors.py
CHANGED
@@ -86,18 +86,54 @@ class ImageProcessorV2:
|
|
86 |
return result, mask
|
87 |
|
88 |
def load_image(self, image, border_ratio=0.15, to_tensor=True):
|
|
|
|
|
|
|
|
|
|
|
89 |
if isinstance(image, str):
|
|
|
90 |
image = cv2.imread(image, cv2.IMREAD_UNCHANGED)
|
|
|
|
|
91 |
image, mask = self.recenter(image, border_ratio=border_ratio)
|
92 |
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
93 |
elif isinstance(image, Image.Image):
|
|
|
94 |
image = image.convert("RGBA")
|
95 |
image = np.asarray(image)
|
96 |
image, mask = self.recenter(image, border_ratio=border_ratio)
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
if to_tensor:
|
103 |
image = array_to_tensor(image)
|
|
|
86 |
return result, mask
|
87 |
|
88 |
def load_image(self, image, border_ratio=0.15, to_tensor=True):
|
89 |
+
# Check for None or empty input
|
90 |
+
if image is None:
|
91 |
+
raise ValueError('Input image is None')
|
92 |
+
|
93 |
+
# Handle different input types
|
94 |
if isinstance(image, str):
|
95 |
+
# Handle file path
|
96 |
image = cv2.imread(image, cv2.IMREAD_UNCHANGED)
|
97 |
+
if image is None:
|
98 |
+
raise ValueError(f'Failed to load image from path')
|
99 |
image, mask = self.recenter(image, border_ratio=border_ratio)
|
100 |
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
101 |
elif isinstance(image, Image.Image):
|
102 |
+
# Handle PIL Image
|
103 |
image = image.convert("RGBA")
|
104 |
image = np.asarray(image)
|
105 |
image, mask = self.recenter(image, border_ratio=border_ratio)
|
106 |
+
elif isinstance(image, np.ndarray):
|
107 |
+
# Handle numpy array
|
108 |
+
if image.size == 0 or image.ndim < 2:
|
109 |
+
raise ValueError(f'Invalid numpy array shape: {image.shape}')
|
110 |
+
|
111 |
+
# Ensure image has proper channels (3 for RGB or 4 for RGBA)
|
112 |
+
if image.ndim == 2: # Grayscale
|
113 |
+
image = np.stack([image, image, image], axis=2)
|
114 |
+
elif image.shape[-1] not in [3, 4]:
|
115 |
+
raise ValueError(f'Invalid image channels: {image.shape[-1]}')
|
116 |
+
|
117 |
+
if image.shape[-1] == 3: # RGB, add alpha channel
|
118 |
+
alpha = np.ones((*image.shape[:2], 1), dtype=image.dtype) * 255
|
119 |
+
image = np.concatenate([image, alpha], axis=-1)
|
120 |
+
|
121 |
+
image, mask = self.recenter(image, border_ratio=border_ratio)
|
122 |
+
else:
|
123 |
+
# Handle other types or unknown formats
|
124 |
+
raise TypeError(f'Unsupported image type: {type(image)}')
|
125 |
+
|
126 |
+
# Validate image before resize
|
127 |
+
if image is None or image.size == 0 or image.ndim < 2:
|
128 |
+
raise ValueError(f'Invalid image after preprocessing, shape: {getattr(image, "shape", None)}')
|
129 |
+
|
130 |
+
# Resize image and mask
|
131 |
+
try:
|
132 |
+
image = cv2.resize(image, (self.size, self.size), interpolation=cv2.INTER_CUBIC)
|
133 |
+
mask = cv2.resize(mask, (self.size, self.size), interpolation=cv2.INTER_NEAREST)
|
134 |
+
mask = mask[..., np.newaxis]
|
135 |
+
except Exception as e:
|
136 |
+
raise ValueError(f'Failed to resize image: {e}, image shape: {getattr(image, "shape", None)}')
|
137 |
|
138 |
if to_tensor:
|
139 |
image = array_to_tensor(image)
|