Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -42,34 +42,113 @@ def verify_pro_status(token: Optional[gr.OAuthToken]) -> bool:
|
|
| 42 |
|
| 43 |
def _extract_image_data_from_response(response) -> Optional[bytes]:
|
| 44 |
"""Helper to extract image data from the model's response."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
if hasattr(response, 'candidates') and response.candidates:
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
return None
|
| 52 |
|
| 53 |
def run_single_image_logic(prompt: str, image_path: Optional[str] = None, progress=gr.Progress()) -> str:
|
| 54 |
"""Handles text-to-image or single image-to-image using Google Gemini."""
|
| 55 |
try:
|
| 56 |
progress(0.2, desc="🎨 준비 중...")
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
if image_path:
|
|
|
|
| 59 |
input_image = Image.open(image_path)
|
| 60 |
contents.append(input_image)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
|
| 62 |
progress(0.5, desc="✨ 생성 중...")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
response = client.models.generate_content(
|
| 64 |
model=GEMINI_MODEL_NAME,
|
| 65 |
contents=contents,
|
|
|
|
| 66 |
)
|
| 67 |
|
|
|
|
|
|
|
|
|
|
| 68 |
progress(0.8, desc="🖼️ 마무리 중...")
|
| 69 |
image_data = _extract_image_data_from_response(response)
|
| 70 |
|
| 71 |
if not image_data:
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
|
| 74 |
# Save the generated image to a temporary file to return its path
|
| 75 |
pil_image = Image.open(BytesIO(image_data))
|
|
@@ -79,6 +158,8 @@ def run_single_image_logic(prompt: str, image_path: Optional[str] = None, progre
|
|
| 79 |
return tmpfile.name
|
| 80 |
|
| 81 |
except Exception as e:
|
|
|
|
|
|
|
| 82 |
raise gr.Error(f"이미지 생성 실패: {e}")
|
| 83 |
|
| 84 |
|
|
@@ -91,20 +172,34 @@ def run_multi_image_logic(prompt: str, images: List[str], progress=gr.Progress()
|
|
| 91 |
|
| 92 |
try:
|
| 93 |
progress(0.2, desc="🎨 이미지 준비 중...")
|
| 94 |
-
contents = [
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
progress(0.5, desc="✨ 생성 중...")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
response = client.models.generate_content(
|
| 99 |
model=GEMINI_MODEL_NAME,
|
| 100 |
contents=contents,
|
|
|
|
| 101 |
)
|
| 102 |
|
|
|
|
|
|
|
|
|
|
| 103 |
progress(0.8, desc="🖼️ 마무리 중...")
|
| 104 |
image_data = _extract_image_data_from_response(response)
|
| 105 |
|
| 106 |
if not image_data:
|
| 107 |
-
raise ValueError("No image data found in the model response.")
|
| 108 |
|
| 109 |
pil_image = Image.open(BytesIO(image_data))
|
| 110 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmpfile:
|
|
@@ -113,6 +208,7 @@ def run_multi_image_logic(prompt: str, images: List[str], progress=gr.Progress()
|
|
| 113 |
return tmpfile.name
|
| 114 |
|
| 115 |
except Exception as e:
|
|
|
|
| 116 |
raise gr.Error(f"이미지 생성 실패: {e}")
|
| 117 |
|
| 118 |
|
|
|
|
| 42 |
|
| 43 |
def _extract_image_data_from_response(response) -> Optional[bytes]:
|
| 44 |
"""Helper to extract image data from the model's response."""
|
| 45 |
+
# Debug: Print response structure
|
| 46 |
+
print(f"Response type: {type(response)}")
|
| 47 |
+
|
| 48 |
+
# Try multiple ways to extract image data
|
| 49 |
+
# Method 1: Direct image attribute
|
| 50 |
+
if hasattr(response, 'image'):
|
| 51 |
+
print("Found response.image")
|
| 52 |
+
return response.image
|
| 53 |
+
|
| 54 |
+
# Method 2: Images array
|
| 55 |
+
if hasattr(response, 'images') and response.images:
|
| 56 |
+
print(f"Found response.images with {len(response.images)} images")
|
| 57 |
+
return response.images[0]
|
| 58 |
+
|
| 59 |
+
# Method 3: Candidates with parts
|
| 60 |
if hasattr(response, 'candidates') and response.candidates:
|
| 61 |
+
print(f"Found {len(response.candidates)} candidates")
|
| 62 |
+
for i, candidate in enumerate(response.candidates):
|
| 63 |
+
print(f"Candidate {i}: {type(candidate)}")
|
| 64 |
+
|
| 65 |
+
# Check for content.parts
|
| 66 |
+
if hasattr(candidate, 'content'):
|
| 67 |
+
print(f" Has content: {type(candidate.content)}")
|
| 68 |
+
if hasattr(candidate.content, 'parts') and candidate.content.parts:
|
| 69 |
+
print(f" Has {len(candidate.content.parts)} parts")
|
| 70 |
+
for j, part in enumerate(candidate.content.parts):
|
| 71 |
+
print(f" Part {j}: {type(part)}")
|
| 72 |
+
|
| 73 |
+
# Check for inline_data
|
| 74 |
+
if hasattr(part, 'inline_data'):
|
| 75 |
+
print(f" Has inline_data")
|
| 76 |
+
if hasattr(part.inline_data, 'data'):
|
| 77 |
+
print(f" Found image data!")
|
| 78 |
+
return part.inline_data.data
|
| 79 |
+
if hasattr(part.inline_data, 'blob'):
|
| 80 |
+
print(f" Found blob data!")
|
| 81 |
+
return part.inline_data.blob
|
| 82 |
+
|
| 83 |
+
# Check for blob directly
|
| 84 |
+
if hasattr(part, 'blob'):
|
| 85 |
+
print(f" Has blob")
|
| 86 |
+
return part.blob
|
| 87 |
+
|
| 88 |
+
# Check for data directly
|
| 89 |
+
if hasattr(part, 'data'):
|
| 90 |
+
print(f" Has data")
|
| 91 |
+
return part.data
|
| 92 |
+
|
| 93 |
+
# Method 4: Text response (might need different API configuration)
|
| 94 |
+
if hasattr(response, 'text'):
|
| 95 |
+
print(f"Response has text but no image: {response.text[:200] if response.text else 'Empty'}")
|
| 96 |
+
|
| 97 |
+
print("No image data found in response")
|
| 98 |
return None
|
| 99 |
|
| 100 |
def run_single_image_logic(prompt: str, image_path: Optional[str] = None, progress=gr.Progress()) -> str:
|
| 101 |
"""Handles text-to-image or single image-to-image using Google Gemini."""
|
| 102 |
try:
|
| 103 |
progress(0.2, desc="🎨 준비 중...")
|
| 104 |
+
|
| 105 |
+
# Prepare the prompt with image generation instruction
|
| 106 |
+
generation_prompt = f"Generate an image: {prompt}"
|
| 107 |
+
|
| 108 |
+
contents = []
|
| 109 |
if image_path:
|
| 110 |
+
# Image-to-image generation
|
| 111 |
input_image = Image.open(image_path)
|
| 112 |
contents.append(input_image)
|
| 113 |
+
contents.append(f"Edit this image: {prompt}")
|
| 114 |
+
else:
|
| 115 |
+
# Text-to-image generation
|
| 116 |
+
contents.append(generation_prompt)
|
| 117 |
|
| 118 |
progress(0.5, desc="✨ 생성 중...")
|
| 119 |
+
|
| 120 |
+
# Try with generation config for images
|
| 121 |
+
generation_config = types.GenerationConfig(
|
| 122 |
+
temperature=1.0,
|
| 123 |
+
max_output_tokens=8192,
|
| 124 |
+
)
|
| 125 |
+
|
| 126 |
response = client.models.generate_content(
|
| 127 |
model=GEMINI_MODEL_NAME,
|
| 128 |
contents=contents,
|
| 129 |
+
generation_config=generation_config,
|
| 130 |
)
|
| 131 |
|
| 132 |
+
# Debug: Print full response
|
| 133 |
+
print(f"Full response: {response}")
|
| 134 |
+
|
| 135 |
progress(0.8, desc="🖼️ 마무리 중...")
|
| 136 |
image_data = _extract_image_data_from_response(response)
|
| 137 |
|
| 138 |
if not image_data:
|
| 139 |
+
# Try alternative approach - generate_images if available
|
| 140 |
+
if hasattr(client.models, 'generate_images'):
|
| 141 |
+
print("Trying generate_images method...")
|
| 142 |
+
response = client.models.generate_images(
|
| 143 |
+
model=GEMINI_MODEL_NAME,
|
| 144 |
+
prompt=prompt,
|
| 145 |
+
n=1,
|
| 146 |
+
)
|
| 147 |
+
if hasattr(response, 'images') and response.images:
|
| 148 |
+
image_data = response.images[0]
|
| 149 |
+
|
| 150 |
+
if not image_data:
|
| 151 |
+
raise ValueError("No image data found in the model response. The API might not support image generation or the model name might be incorrect.")
|
| 152 |
|
| 153 |
# Save the generated image to a temporary file to return its path
|
| 154 |
pil_image = Image.open(BytesIO(image_data))
|
|
|
|
| 158 |
return tmpfile.name
|
| 159 |
|
| 160 |
except Exception as e:
|
| 161 |
+
print(f"Error details: {e}")
|
| 162 |
+
print(f"Error type: {type(e)}")
|
| 163 |
raise gr.Error(f"이미지 생성 실패: {e}")
|
| 164 |
|
| 165 |
|
|
|
|
| 172 |
|
| 173 |
try:
|
| 174 |
progress(0.2, desc="🎨 이미지 준비 중...")
|
| 175 |
+
contents = []
|
| 176 |
+
for image_path in images:
|
| 177 |
+
if isinstance(image_path, (list, tuple)):
|
| 178 |
+
image_path = image_path[0]
|
| 179 |
+
contents.append(Image.open(image_path))
|
| 180 |
+
contents.append(f"Combine/edit these images: {prompt}")
|
| 181 |
|
| 182 |
progress(0.5, desc="✨ 생성 중...")
|
| 183 |
+
|
| 184 |
+
generation_config = types.GenerationConfig(
|
| 185 |
+
temperature=1.0,
|
| 186 |
+
max_output_tokens=8192,
|
| 187 |
+
)
|
| 188 |
+
|
| 189 |
response = client.models.generate_content(
|
| 190 |
model=GEMINI_MODEL_NAME,
|
| 191 |
contents=contents,
|
| 192 |
+
generation_config=generation_config,
|
| 193 |
)
|
| 194 |
|
| 195 |
+
# Debug: Print full response
|
| 196 |
+
print(f"Multi-image response: {response}")
|
| 197 |
+
|
| 198 |
progress(0.8, desc="🖼️ 마무리 중...")
|
| 199 |
image_data = _extract_image_data_from_response(response)
|
| 200 |
|
| 201 |
if not image_data:
|
| 202 |
+
raise ValueError("No image data found in the model response. The API might not support multi-image generation.")
|
| 203 |
|
| 204 |
pil_image = Image.open(BytesIO(image_data))
|
| 205 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmpfile:
|
|
|
|
| 208 |
return tmpfile.name
|
| 209 |
|
| 210 |
except Exception as e:
|
| 211 |
+
print(f"Multi-image error details: {e}")
|
| 212 |
raise gr.Error(f"이미지 생성 실패: {e}")
|
| 213 |
|
| 214 |
|