Hammad712 commited on
Commit
0c779fa
·
verified ·
1 Parent(s): bbabac5

Update app/services/image_service.py

Browse files
Files changed (1) hide show
  1. app/services/image_service.py +38 -28
app/services/image_service.py CHANGED
@@ -12,27 +12,28 @@ from app.core.clients import llm, prompt_template, genai_client, flux_client, ge
12
 
13
  logger = logging.getLogger(__name__)
14
 
15
- # --- Virtual Try-On Instruction Template ---
16
  VIRTUAL_TRY_ON_PROMPT = """
17
- You are an expert image-editing agent. Perform a high-fidelity virtual try-on using two inputs:
18
 
19
  - Input 1 (dress reference): the exact garment image to be transferred.
20
  - Input 2 (person): the target person who must wear the garment.
 
21
 
22
  Positive instructions (Do):
23
- 1. Produce exactly one photorealistic output image showing the person wearing the dress from Input 1.
24
  2. Preserve the person's face, facial features, expression, hair, gender, skin tone, and body proportions — do NOT change identity.
25
- 3. Reproduce the dress design, color, pattern, fabric texture, and major details (buttons, seams, prints) faithfully — do NOT change these.
26
- 4. Match lighting, shadows, perspective, and scale so the garment appears naturally worn by the person.
27
- 5. If minor geometric adjustments are required to account for pose, make them subtle and keep dress details intact.
28
  6. Also return a short text JSON summary with the form: {"success": true|false, "notes": "explain any limitations or changes"}.
29
 
30
  Negative instructions (Do NOT):
31
  1. Do NOT modify the person's face, gender, or identifying features.
32
- 2. Do NOT change the dress color, pattern, or main texture.
33
  3. Do NOT add extra clothing items, logos, watermarks, offensive symbols, or unrelated props.
34
  4. Do NOT produce empty responses, placeholders, or images containing text overlays.
35
- 5. Do NOT blur, heavily distort, or crop important parts of the person or dress.
36
 
37
  Output requirements:
38
  - Return a single photorealistic image (same orientation as the person image) and a short text JSON summary.
@@ -153,23 +154,43 @@ def update_image_with_text(text_instruction: str, image_bytes: bytes) -> tuple[O
153
 
154
 
155
  # ===============================================================
156
- # 🔹 VIRTUAL TRY-ON (DRESS + PERSON)
157
  # ===============================================================
158
- def virtual_try_on(dress_image_bytes: bytes, person_image_bytes: bytes) -> tuple[Dict[str, Any], Optional[BytesIO]]:
159
- """Perform virtual try-on with Gemini, fallback to Flux if fails."""
 
 
 
 
160
  logger.info("Opening images for virtual try-on...")
161
 
162
  try:
163
  dress_image = Image.open(BytesIO(dress_image_bytes))
164
  person_image = Image.open(BytesIO(person_image_bytes))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  except Exception:
166
  raise ValueError("Invalid image data provided.")
167
 
168
  try:
169
  config = types.GenerateContentConfig(response_modalities=["Text", "Image"])
 
 
170
  response = genai_client1.models.generate_content(
171
- model="gemini-2.5-flash-image",
172
- contents=[VIRTUAL_TRY_ON_PROMPT, dress_image, person_image],
173
  config=config
174
  )
175
 
@@ -190,23 +211,12 @@ def virtual_try_on(dress_image_bytes: bytes, person_image_bytes: bytes) -> tuple
190
  return result_summary, result_image_bytes
191
 
192
  except Exception as e:
193
- logger.warning(f"Gemini try-on failed: {e}. Falling back to Flux...")
194
-
195
- # try:
196
- # prompt = "Photorealistic virtual try-on of a person wearing the given dress."
197
- # image = flux_client.text_to_image(
198
- # prompt,
199
- # model="black-forest-labs/FLUX.1-dev"
200
- # )
201
- # buf = BytesIO()
202
- # image.save(buf, format="PNG")
203
- # buf.seek(0)
204
- # return {"success": True, "notes": "Generated using Flux fallback."}, buf
205
- # except Exception as flux_error:
206
- # logger.error(f"Flux fallback failed: {flux_error}", exc_info=True)
207
- # raise
208
 
209
 
 
210
  # ===============================================================
211
  # 🔹 SHOE IMAGE GENERATION
212
  # ===============================================================
 
12
 
13
  logger = logging.getLogger(__name__)
14
 
15
+ # --- Virtual Try-On Instruction Template (Updated for 3 Inputs) ---
16
  VIRTUAL_TRY_ON_PROMPT = """
17
+ You are an expert image-editing agent. Perform a high-fidelity virtual try-on using three inputs:
18
 
19
  - Input 1 (dress reference): the exact garment image to be transferred.
20
  - Input 2 (person): the target person who must wear the garment.
21
+ - Input 3 (shoes reference): the footwear to be worn.
22
 
23
  Positive instructions (Do):
24
+ 1. Produce exactly one photorealistic output image showing the person from Input 2 wearing BOTH the dress from Input 1 and the shoes from Input 3.
25
  2. Preserve the person's face, facial features, expression, hair, gender, skin tone, and body proportions — do NOT change identity.
26
+ 3. Reproduce the dress design, color, pattern, fabric texture, and major details (buttons, seams, prints) faithfully.
27
+ 4. Reproduce the shoes faithfully and ensure they fit the person's stance naturally (grounding, shadows).
28
+ 5. Match lighting, shadows, perspective, and scale so all items appear naturally worn by the person in the original scene.
29
  6. Also return a short text JSON summary with the form: {"success": true|false, "notes": "explain any limitations or changes"}.
30
 
31
  Negative instructions (Do NOT):
32
  1. Do NOT modify the person's face, gender, or identifying features.
33
+ 2. Do NOT change the dress/shoe color, pattern, or main texture.
34
  3. Do NOT add extra clothing items, logos, watermarks, offensive symbols, or unrelated props.
35
  4. Do NOT produce empty responses, placeholders, or images containing text overlays.
36
+ 5. Do NOT blur, heavily distort, or crop important parts of the person, dress, or shoes.
37
 
38
  Output requirements:
39
  - Return a single photorealistic image (same orientation as the person image) and a short text JSON summary.
 
154
 
155
 
156
  # ===============================================================
157
+ # 🔹 VIRTUAL TRY-ON (DRESS + PERSON + SHOES)
158
  # ===============================================================
159
+ def virtual_try_on(
160
+ dress_image_bytes: bytes,
161
+ person_image_bytes: bytes,
162
+ shoes_image_bytes: Optional[bytes] = None
163
+ ) -> tuple[Dict[str, Any], Optional[BytesIO]]:
164
+ """Perform virtual try-on with Gemini (Supports optional shoes)."""
165
  logger.info("Opening images for virtual try-on...")
166
 
167
  try:
168
  dress_image = Image.open(BytesIO(dress_image_bytes))
169
  person_image = Image.open(BytesIO(person_image_bytes))
170
+
171
+ # Prepare content list with mandatory items
172
+ contents = [VIRTUAL_TRY_ON_PROMPT, dress_image, person_image]
173
+
174
+ # Handle optional shoes
175
+ if shoes_image_bytes:
176
+ shoes_image = Image.open(BytesIO(shoes_image_bytes))
177
+ contents.append(shoes_image) # Appends as Input 3
178
+ else:
179
+ # If no shoes provided, you might want to append a text note
180
+ # telling the model to ignore Input 3 instructions,
181
+ # or simply rely on the model's flexibility.
182
+ pass
183
+
184
  except Exception:
185
  raise ValueError("Invalid image data provided.")
186
 
187
  try:
188
  config = types.GenerateContentConfig(response_modalities=["Text", "Image"])
189
+
190
+ # Make the API call with all collected contents
191
  response = genai_client1.models.generate_content(
192
+ model="gemini-2.0-flash-exp", # Ensure this model supports image gen
193
+ contents=contents,
194
  config=config
195
  )
196
 
 
211
  return result_summary, result_image_bytes
212
 
213
  except Exception as e:
214
+ logger.warning(f"Gemini try-on failed: {e}")
215
+ # Re-raise or handle fallback logic here
216
+ raise HTTPException(status_code=500, detail=f"Model generation failed: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
217
 
218
 
219
+
220
  # ===============================================================
221
  # 🔹 SHOE IMAGE GENERATION
222
  # ===============================================================