Spaces:
Sleeping
Sleeping
換成GOOGLE格式
Browse files- image_examples.py +52 -26
image_examples.py
CHANGED
|
@@ -239,35 +239,61 @@ def generate_video_from_image(image_path):
|
|
| 239 |
|
| 240 |
prompt = "請根據這張圖片生成一段有創意的短影片,內容需與圖片主題高度相關。"
|
| 241 |
|
| 242 |
-
#
|
| 243 |
with open(image_path, "rb") as img_file:
|
| 244 |
img_bytes = img_file.read()
|
| 245 |
|
| 246 |
-
#
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
|
|
|
| 259 |
|
| 260 |
-
|
| 261 |
-
time.sleep(10)
|
| 262 |
-
operation = client.operations.get(operation)
|
| 263 |
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 273 |
return image_path
|
|
|
|
| 239 |
|
| 240 |
prompt = "請根據這張圖片生成一段有創意的短影片,內容需與圖片主題高度相關。"
|
| 241 |
|
| 242 |
+
# 1. 讀取本地圖片的二進制數據
|
| 243 |
with open(image_path, "rb") as img_file:
|
| 244 |
img_bytes = img_file.read()
|
| 245 |
|
| 246 |
+
# 2. 判斷圖片的 MIME type (這裡假設 .jpg 都是 image/jpeg)
|
| 247 |
+
# 更可靠的方式是使用 imghdr 庫或類似方法來檢測
|
| 248 |
+
mime_type = "image/jpeg"
|
| 249 |
+
if image_path.lower().endswith(".png"):
|
| 250 |
+
mime_type = "image/png"
|
| 251 |
+
# Add more types if needed
|
| 252 |
+
|
| 253 |
+
# 3. 建立 GeminiImage 物件
|
| 254 |
+
# 使用 image_bytes 參數來傳遞圖片數據
|
| 255 |
+
try:
|
| 256 |
+
gemini_image_obj = GeminiImage(image_bytes=img_bytes, mime_type=mime_type)
|
| 257 |
+
except Exception as e:
|
| 258 |
+
print(f"[ERROR] Failed to create GeminiImage object: {e}")
|
| 259 |
+
return image_path # Fallback: return original path if image object creation fails
|
| 260 |
|
| 261 |
+
print(f"[LOG] Attempting to generate video with image: {image_path}, mime_type: {mime_type}")
|
|
|
|
|
|
|
| 262 |
|
| 263 |
+
try:
|
| 264 |
+
operation = client.models.generate_videos(
|
| 265 |
+
model="veo-2.0-generate-001",
|
| 266 |
+
prompt=prompt,
|
| 267 |
+
image=gemini_image_obj, # 傳遞 GeminiImage 物件
|
| 268 |
+
config=types.GenerateVideosConfig(
|
| 269 |
+
person_generation="dont_allow",
|
| 270 |
+
aspect_ratio="16:9",
|
| 271 |
+
number_of_videos=1
|
| 272 |
+
),
|
| 273 |
+
)
|
| 274 |
+
|
| 275 |
+
while not operation.done:
|
| 276 |
+
print("[LOG] Waiting for video generation to complete...")
|
| 277 |
+
time.sleep(10) # 官方範例用 20 秒,可依需求調整
|
| 278 |
+
operation = client.operations.get(operation)
|
| 279 |
+
|
| 280 |
+
image_dir = os.path.join(os.getcwd(), "images")
|
| 281 |
+
if operation.response and operation.response.generated_videos:
|
| 282 |
+
for n, video in enumerate(operation.response.generated_videos):
|
| 283 |
+
fname = f"{os.path.splitext(os.path.basename(image_path))[0]}_veo{n}.mp4"
|
| 284 |
+
save_path = os.path.join(image_dir, fname)
|
| 285 |
+
video.video.save(save_path)
|
| 286 |
+
print(f"[LOG] 影片已儲存:{save_path}")
|
| 287 |
+
return save_path
|
| 288 |
+
else:
|
| 289 |
+
print("[LOG] Video generation completed but no videos were returned in the response.")
|
| 290 |
+
if operation.error:
|
| 291 |
+
print(f"[ERROR] Video generation failed with error: {operation.error.message}")
|
| 292 |
+
return image_path
|
| 293 |
+
|
| 294 |
+
except Exception as e:
|
| 295 |
+
print(f"[ERROR] Exception during video generation or saving: {e}")
|
| 296 |
+
return image_path # Fallback
|
| 297 |
+
|
| 298 |
+
print("[LOG] 未產生影片或處理出錯,回傳原圖路徑")
|
| 299 |
return image_path
|