akhaliq HF Staff commited on
Commit
f51faa0
·
1 Parent(s): 958a4aa

add nano banana

Browse files
Files changed (1) hide show
  1. app.py +83 -38
app.py CHANGED
@@ -2175,46 +2175,41 @@ def generate_image_with_qwen(prompt: str, image_index: int = 0, token: gr.OAuthT
2175
  return f"Error generating image: {str(e)}"
2176
 
2177
  def generate_image_to_image(input_image_data, prompt: str, token: gr.OAuthToken | None = None) -> str:
2178
- """Generate an image using image-to-image with Qwen-Image-Edit via Hugging Face InferenceClient.
2179
 
2180
- Returns an HTML <img> tag with optimized base64 JPEG data, similar to text-to-image output.
 
 
2181
  """
2182
  try:
2183
- # Check token
2184
- if not os.getenv('HF_TOKEN'):
2185
- return "Error: HF_TOKEN environment variable is not set. Please set it to your Hugging Face API token."
2186
-
2187
- # Prepare client
2188
- client = InferenceClient(
2189
- provider="auto",
2190
- api_key=os.getenv('HF_TOKEN'),
2191
- bill_to="huggingface",
2192
- )
2193
 
2194
  # Normalize input image to bytes
2195
  import io
2196
  from PIL import Image
 
 
 
2197
  try:
2198
  import numpy as np
2199
  except Exception:
2200
  np = None
2201
 
2202
  if hasattr(input_image_data, 'read'):
2203
- # File-like object
2204
  raw = input_image_data.read()
2205
  pil_image = Image.open(io.BytesIO(raw))
2206
  elif hasattr(input_image_data, 'mode') and hasattr(input_image_data, 'size'):
2207
- # PIL Image
2208
  pil_image = input_image_data
2209
  elif np is not None and isinstance(input_image_data, np.ndarray):
2210
  pil_image = Image.fromarray(input_image_data)
2211
  elif isinstance(input_image_data, (bytes, bytearray)):
2212
  pil_image = Image.open(io.BytesIO(input_image_data))
2213
  else:
2214
- # Fallback: try to convert via bytes
2215
  pil_image = Image.open(io.BytesIO(bytes(input_image_data)))
2216
 
2217
- # Ensure RGB
2218
  if pil_image.mode != 'RGB':
2219
  pil_image = pil_image.convert('RGB')
2220
 
@@ -2223,34 +2218,84 @@ def generate_image_to_image(input_image_data, prompt: str, token: gr.OAuthToken
2223
  if pil_image.width > max_input_size or pil_image.height > max_input_size:
2224
  pil_image.thumbnail((max_input_size, max_input_size), Image.Resampling.LANCZOS)
2225
 
2226
- buf = io.BytesIO()
2227
- pil_image.save(buf, format='JPEG', quality=85, optimize=True)
2228
- input_bytes = buf.getvalue()
2229
-
2230
- # Call image-to-image
2231
- image = client.image_to_image(
2232
- input_bytes,
2233
- prompt=prompt,
2234
- model="Qwen/Qwen-Image-Edit",
2235
- )
2236
-
2237
- # Resize/optimize (larger since not using data URIs)
2238
- max_size = 1024
2239
- if image.width > max_size or image.height > max_size:
2240
- image.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
2241
 
2242
- out_buf = io.BytesIO()
2243
- image.convert('RGB').save(out_buf, format='JPEG', quality=90, optimize=True)
2244
- image_bytes = out_buf.getvalue()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2245
 
2246
- # Create temporary URL for preview (will be uploaded to HF during deploy)
2247
  filename = "image_to_image_result.jpg"
2248
  temp_url = upload_media_to_hf(image_bytes, filename, "image", token, use_temp=True)
2249
-
2250
- # Check if creation was successful
2251
  if temp_url.startswith("Error"):
2252
  return temp_url
2253
-
2254
  return f"<img src=\"{temp_url}\" alt=\"{prompt}\" style=\"max-width: 100%; height: auto; border-radius: 8px; margin: 10px 0;\" loading=\"lazy\" />"
2255
  except Exception as e:
2256
  print(f"Image-to-image generation error: {str(e)}")
 
2175
  return f"Error generating image: {str(e)}"
2176
 
2177
  def generate_image_to_image(input_image_data, prompt: str, token: gr.OAuthToken | None = None) -> str:
2178
+ """Generate an image using image-to-image via OpenRouter.
2179
 
2180
+ Uses Google Gemini 2.5 Flash Image Preview via OpenRouter chat completions API.
2181
+
2182
+ Returns an HTML <img> tag whose src is an uploaded temporary URL.
2183
  """
2184
  try:
2185
+ # Check for OpenRouter API key
2186
+ openrouter_key = os.getenv('OPENROUTER_API_KEY')
2187
+ if not openrouter_key:
2188
+ return "Error: OPENROUTER_API_KEY environment variable is not set. Please set it to your OpenRouter API key."
 
 
 
 
 
 
2189
 
2190
  # Normalize input image to bytes
2191
  import io
2192
  from PIL import Image
2193
+ import base64
2194
+ import requests
2195
+ import json as _json
2196
  try:
2197
  import numpy as np
2198
  except Exception:
2199
  np = None
2200
 
2201
  if hasattr(input_image_data, 'read'):
 
2202
  raw = input_image_data.read()
2203
  pil_image = Image.open(io.BytesIO(raw))
2204
  elif hasattr(input_image_data, 'mode') and hasattr(input_image_data, 'size'):
 
2205
  pil_image = input_image_data
2206
  elif np is not None and isinstance(input_image_data, np.ndarray):
2207
  pil_image = Image.fromarray(input_image_data)
2208
  elif isinstance(input_image_data, (bytes, bytearray)):
2209
  pil_image = Image.open(io.BytesIO(input_image_data))
2210
  else:
 
2211
  pil_image = Image.open(io.BytesIO(bytes(input_image_data)))
2212
 
 
2213
  if pil_image.mode != 'RGB':
2214
  pil_image = pil_image.convert('RGB')
2215
 
 
2218
  if pil_image.width > max_input_size or pil_image.height > max_input_size:
2219
  pil_image.thumbnail((max_input_size, max_input_size), Image.Resampling.LANCZOS)
2220
 
2221
+ # Convert to base64
2222
+ import io as _io
2223
+ buffered = _io.BytesIO()
2224
+ pil_image.save(buffered, format='PNG')
2225
+ img_b64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
 
 
 
 
 
 
 
 
 
 
2226
 
2227
+ # Call OpenRouter API
2228
+ headers = {
2229
+ "Authorization": f"Bearer {openrouter_key}",
2230
+ "Content-Type": "application/json",
2231
+ "HTTP-Referer": os.getenv("YOUR_SITE_URL", "https://example.com"),
2232
+ "X-Title": os.getenv("YOUR_SITE_NAME", "AnyCoder Image I2I"),
2233
+ }
2234
+ payload = {
2235
+ "model": "google/gemini-2.5-flash-image-preview:free",
2236
+ "messages": [
2237
+ {
2238
+ "role": "user",
2239
+ "content": [
2240
+ {"type": "text", "text": prompt},
2241
+ {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img_b64}"}},
2242
+ ],
2243
+ }
2244
+ ],
2245
+ "max_tokens": 2048,
2246
+ }
2247
+
2248
+ try:
2249
+ resp = requests.post(
2250
+ "https://openrouter.ai/api/v1/chat/completions",
2251
+ headers=headers,
2252
+ data=_json.dumps(payload),
2253
+ timeout=60,
2254
+ )
2255
+ resp.raise_for_status()
2256
+ result_data = resp.json()
2257
+
2258
+ # Corrected response parsing logic
2259
+ message = result_data.get('choices', [{}])[0].get('message', {})
2260
+
2261
+ if message and 'images' in message and message['images']:
2262
+ # Get the first image from the 'images' list
2263
+ image_data = message['images'][0]
2264
+ base64_string = image_data.get('image_url', {}).get('url', '')
2265
+
2266
+ if base64_string and ',' in base64_string:
2267
+ # Remove the "data:image/png;base64," prefix
2268
+ base64_content = base64_string.split(',')[1]
2269
+
2270
+ # Decode the base64 string and create a PIL image
2271
+ img_bytes = base64.b64decode(base64_content)
2272
+ edited_image = Image.open(_io.BytesIO(img_bytes))
2273
+
2274
+ # Convert PIL image to JPEG bytes for upload
2275
+ out_buf = _io.BytesIO()
2276
+ edited_image.convert('RGB').save(out_buf, format='JPEG', quality=90, optimize=True)
2277
+ image_bytes = out_buf.getvalue()
2278
+ else:
2279
+ raise RuntimeError(f"API returned an invalid image format. Response: {_json.dumps(result_data, indent=2)}")
2280
+ else:
2281
+ raise RuntimeError(f"API did not return an image. Full Response: {_json.dumps(result_data, indent=2)}")
2282
+
2283
+ except requests.exceptions.HTTPError as err:
2284
+ error_body = err.response.text
2285
+ if err.response.status_code == 401:
2286
+ return "Error: Authentication failed. Check your OpenRouter API key."
2287
+ elif err.response.status_code == 429:
2288
+ return "Error: Rate limit exceeded or insufficient credits. Check your OpenRouter account."
2289
+ else:
2290
+ return f"Error: An API error occurred: {error_body}"
2291
+ except Exception as e:
2292
+ return f"Error: An unexpected error occurred: {str(e)}"
2293
 
2294
+ # Upload and return HTML tag
2295
  filename = "image_to_image_result.jpg"
2296
  temp_url = upload_media_to_hf(image_bytes, filename, "image", token, use_temp=True)
 
 
2297
  if temp_url.startswith("Error"):
2298
  return temp_url
 
2299
  return f"<img src=\"{temp_url}\" alt=\"{prompt}\" style=\"max-width: 100%; height: auto; border-radius: 8px; margin: 10px 0;\" loading=\"lazy\" />"
2300
  except Exception as e:
2301
  print(f"Image-to-image generation error: {str(e)}")