abhinav0231 commited on
Commit
3aa60f4
Β·
verified Β·
1 Parent(s): efbc3d2

Update image_generation.py

Browse files
Files changed (1) hide show
  1. image_generation.py +51 -72
image_generation.py CHANGED
@@ -3,14 +3,13 @@ import mimetypes
3
  import json
4
  import streamlit as st
5
  import google.generativeai as genai
6
- from typing import List, Dict, Optional
7
  from PIL import Image
8
  import io
9
  import traceback
10
  import time
11
 
12
- # Initialization
13
- client = None
14
  try:
15
  api_key = st.secrets.get("GEMINI_API_KEY") or os.getenv("GEMINI_API_KEY")
16
  if api_key:
@@ -31,64 +30,54 @@ def save_binary_file(file_name: str, data: bytes):
31
  print(f"❌ Error saving file {file_name}: {e}")
32
 
33
  # --- IMAGE GENERATION FUNCTION ---
34
- # --- CORRECTED IMAGE GENERATION FUNCTION ---
35
  def generate_image_with_gemini(
36
  prompt: str,
37
  output_file_base: str,
38
  context_image: Optional[Image.Image] = None
39
  ) -> Optional[str]:
40
  """
41
- Generates an image using the correct syntax for your library version.
42
  """
43
  print(f"--- 🎨 Generating image for prompt: '{prompt[:70]}...' ---")
44
  try:
45
- # 1. Create the model instance directly
46
  model = genai.GenerativeModel(model_name="gemini-2.5-flash-image-preview")
47
 
48
- # 2. Create the content list
49
  content_parts = []
50
  if context_image:
51
- print(" -> Using previous image as context for consistent styling.")
52
  content_parts.extend([prompt, context_image])
53
  else:
54
  content_parts.append(prompt)
55
 
56
- # 3. Make the call on the model object
57
  response = model.generate_content(
58
  contents=content_parts,
59
  stream=True
60
  )
61
 
62
  saved_file_path = None
63
- text_responses = []
64
-
65
- # 4. Process the response
66
  for chunk in response:
67
- if chunk.parts:
68
- for part in chunk.parts:
69
- if part.inline_data:
70
- data = part.inline_data.data
71
- mime_type = part.inline_data.mime_type
72
- file_extension = mimetypes.guess_extension(mime_type) or ".jpg"
73
- full_file_name = f"{output_file_base}{file_extension}"
74
-
75
- save_binary_file(full_file_name, data)
76
- saved_file_path = full_file_name
77
- print(f"βœ… Successfully generated and saved image: {full_file_name}")
78
- break
79
- elif part.text:
80
- text_responses.append(part.text)
81
 
82
- if not saved_file_path and text_responses:
83
- print(f"⚠️ No image generated. API returned text: {''.join(text_responses)}")
84
-
85
- return saved_file_path
86
 
 
 
 
 
87
  except Exception as e:
88
  print(f"❌ An error occurred during the Gemini API call: {e}")
89
  traceback.print_exc()
90
  return None
91
 
 
92
  def generate_all_images_from_file(
93
  json_path: str,
94
  output_dir: str = "generated_images",
@@ -101,67 +90,57 @@ def generate_all_images_from_file(
101
  print(f"❌ Error reading or parsing {json_path}: {e}")
102
  return []
103
 
104
- if not os.path.exists(output_dir):
105
- os.makedirs(output_dir)
 
 
 
106
 
107
- previous_image = None
108
- successful_generations = 0
109
 
 
110
  for i, item in enumerate(multimedia_data):
111
  print(f"\n{'='*60}")
112
- print(f"Processing item {i+1}/{len(multimedia_data)} - {'FIRST IMAGE' if i == 0 else 'CONTINUATION'}")
113
- print(f"{'='*60}")
114
 
115
  image_prompt = item.get("image_prompt")
116
  if not image_prompt or "Error:" in image_prompt:
117
- print(f"⚠️ Skipping item {i}: No valid image prompt found")
118
  item["image_path"] = None
119
  continue
120
 
121
- print(f"πŸ“ Image prompt: {image_prompt[:100]}{'...' if len(image_prompt) > 100 else ''}")
122
  file_base_path = os.path.join(output_dir, f"image_{i:03d}")
123
 
124
- # Your system prompts are now integrated into the main prompt for simplicity
125
- if previous_image:
126
- full_prompt = f"""You are a master storyboard artist creating a visual story sequence. IMPORTANT: You MUST generate an image. Maintain consistency with the provided image. Style: Cinematic, epic fantasy digital painting. Generate an image that illustrates the following scene: {image_prompt}"""
127
- else:
128
- full_prompt = f"""You are a master storyboard artist creating the opening scene. IMPORTANT: You MUST generate an image. Style: Stunning, cinematic, epic fantasy digital painting with rich detail and dramatic lighting. Generate an image that illustrates: {image_prompt}"""
129
-
130
-
131
- saved_image_path = generate_image_with_gemini(
132
- full_prompt,
133
- file_base_path,
134
- context_image=previous_image
135
- )
136
-
 
 
137
  item["image_path"] = saved_image_path
138
 
139
- if saved_image_path and os.path.exists(saved_image_path):
140
  try:
141
  previous_image = Image.open(saved_image_path)
142
- successful_generations += 1
143
- print(f"βœ… Loaded image {saved_image_path} as context for next generation.")
144
  except Exception as e:
145
- print(f"⚠️ Could not load image {saved_image_path} for context. Error: {e}")
146
  previous_image = None
147
  else:
148
  previous_image = None
149
- print("❌ No image generated for this item!")
150
 
151
- time.sleep(2)
152
-
153
- try:
154
- with open(output_json_path, 'w', encoding='utf-8') as f:
155
- json.dump(multimedia_data, f, indent=2, ensure_ascii=False)
156
- print(f"\n--- βœ… Image generation finished. Updated data saved to {output_json_path}. ---")
157
- print(f"Successfully generated {successful_generations}/{len(multimedia_data)} images.")
158
-
159
- print(f"\nπŸ“Š GENERATION SUMMARY:")
160
- for i, item in enumerate(multimedia_data):
161
- status = "βœ… SUCCESS" if item.get("image_path") else "❌ FAILED"
162
- print(f" Item {i+1}: {status}")
163
-
164
- except Exception as e:
165
- print(f"❌ Error saving updated JSON: {e}")
166
 
167
- return multimedia_data
 
 
 
 
3
  import json
4
  import streamlit as st
5
  import google.generativeai as genai
6
+ import google.api_core.exceptions
7
  from PIL import Image
8
  import io
9
  import traceback
10
  import time
11
 
12
+ # --- INITIALIZATION ---
 
13
  try:
14
  api_key = st.secrets.get("GEMINI_API_KEY") or os.getenv("GEMINI_API_KEY")
15
  if api_key:
 
30
  print(f"❌ Error saving file {file_name}: {e}")
31
 
32
  # --- IMAGE GENERATION FUNCTION ---
 
33
  def generate_image_with_gemini(
34
  prompt: str,
35
  output_file_base: str,
36
  context_image: Optional[Image.Image] = None
37
  ) -> Optional[str]:
38
  """
39
+ Generates an image and now specifically handles ResourceExhausted errors.
40
  """
41
  print(f"--- 🎨 Generating image for prompt: '{prompt[:70]}...' ---")
42
  try:
 
43
  model = genai.GenerativeModel(model_name="gemini-2.5-flash-image-preview")
44
 
 
45
  content_parts = []
46
  if context_image:
 
47
  content_parts.extend([prompt, context_image])
48
  else:
49
  content_parts.append(prompt)
50
 
 
51
  response = model.generate_content(
52
  contents=content_parts,
53
  stream=True
54
  )
55
 
56
  saved_file_path = None
 
 
 
57
  for chunk in response:
58
+ if chunk.parts and chunk.parts[0].inline_data:
59
+ part = chunk.parts[0]
60
+ data = part.inline_data.data
61
+ mime_type = part.inline_data.mime_type
62
+ file_extension = mimetypes.guess_extension(mime_type) or ".jpg"
63
+ full_file_name = f"{output_file_base}{file_extension}"
64
+ save_binary_file(full_file_name, data)
65
+ saved_file_path = full_file_name
66
+ print(f"βœ… Successfully generated and saved image: {full_file_name}")
67
+ return saved_file_path
 
 
 
 
68
 
69
+ return None # Return None if no image was generated
 
 
 
70
 
71
+ except google.api_core.exceptions.ResourceExhausted as e:
72
+ # --- CATCH and signal the rate limit error ---
73
+ print(f"πŸ”΄ RATE LIMIT EXCEEDED. The script will wait and retry.")
74
+ return "RATE_LIMIT_EXCEEDED"
75
  except Exception as e:
76
  print(f"❌ An error occurred during the Gemini API call: {e}")
77
  traceback.print_exc()
78
  return None
79
 
80
+ # --- MAIN FUNCTION ---
81
  def generate_all_images_from_file(
82
  json_path: str,
83
  output_dir: str = "generated_images",
 
90
  print(f"❌ Error reading or parsing {json_path}: {e}")
91
  return []
92
 
93
+ # --- ADDED: Daily Limit Guard ---
94
+ if len(multimedia_data) > 100:
95
+ print(f"⚠️ WARNING: Your request for {len(multimedia_data)} images exceeds the daily limit of 100.")
96
+ print("Processing will stop to avoid hitting the daily rate limit.")
97
+ return multimedia_data
98
 
99
+ os.makedirs(output_dir, exist_ok=True)
 
100
 
101
+ previous_image = None
102
  for i, item in enumerate(multimedia_data):
103
  print(f"\n{'='*60}")
104
+ print(f"Processing item {i+1}/{len(multimedia_data)}")
 
105
 
106
  image_prompt = item.get("image_prompt")
107
  if not image_prompt or "Error:" in image_prompt:
 
108
  item["image_path"] = None
109
  continue
110
 
 
111
  file_base_path = os.path.join(output_dir, f"image_{i:03d}")
112
 
113
+ # --- Retry Logic ---
114
+ max_retries = 3
115
+ for attempt in range(max_retries):
116
+ saved_image_path = generate_image_with_gemini(
117
+ image_prompt, file_base_path, context_image=previous_image
118
+ )
119
+
120
+ if saved_image_path == "RATE_LIMIT_EXCEEDED":
121
+ wait_time = 60 # Wait for 60 seconds
122
+ print(f"Retrying in {wait_time} seconds (Attempt {attempt + 1}/{max_retries})...")
123
+ time.sleep(wait_time)
124
+ continue
125
+ else:
126
+ break
127
+
128
  item["image_path"] = saved_image_path
129
 
130
+ if saved_image_path and saved_image_path != "RATE_LIMIT_EXCEEDED":
131
  try:
132
  previous_image = Image.open(saved_image_path)
 
 
133
  except Exception as e:
 
134
  previous_image = None
135
  else:
136
  previous_image = None
137
+ print("❌ Failed to generate an image for this item after retries.")
138
 
139
+ # --- Increased delay for RPM limit ---
140
+ print("Waiting 7 seconds before next request...")
141
+ time.sleep(7)
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
+ with open(output_json_path, 'w', encoding='utf-8') as f:
144
+ json.dump(multimedia_data, f, indent=2, ensure_ascii=False)
145
+
146
+ return multimedia_data