gen_images.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. # -*- coding: utf-8 -*-
  2. """Step 5b: 批量生成 22 张 PPT 配图(Agnes API, agnes-image-2.0-flash)"""
  3. import json, os, sys, time, urllib.request, urllib.error
  4. sys.stdout.reconfigure(encoding='utf-8')
  5. BASE = r"D:\workspace\cfc\ppt-output"
  6. OUT_DIR = os.path.join(BASE, "images")
  7. API_URL = "https://apihub.agnes-ai.cn/v1/images/generations"
  8. TOKEN = "sk-MyLS4uAAWAIGnJLK2UKuFrL1GotnsFX1XqJ57MZq0n208sNb"
  9. MODEL = "agnes-image-2.0-flash"
  10. os.makedirs(OUT_DIR, exist_ok=True)
  11. # ---- 22 张配图定义:slide_no, card_idx, usage, placement, prompt ----
  12. STYLE = ("Warm, premium flat illustration with soft 3D depth, family health AI platform theme. "
  13. "Color palette: deep tech navy blue background (#0A1A2F) with warm orange (#FF8C42) accents "
  14. "and soft golden light glow. Clean, minimalist. No text, no words, no letters, no numbers, no logos. 1024x1024.")
  15. COMPOSITION = {
  16. "full-bleed": "Scene fills the entire canvas edge-to-edge with balanced composition.",
  17. "right-half": "Main subject on the left side, large empty negative space on the right side for text overlay.",
  18. "inline": "Centered composition, balanced, suitable for a small card illustration.",
  19. }
  20. IMAGES = [
  21. (1, 0, "hero-background", "full-bleed",
  22. "A warm family scene: parents and child sitting together in golden sunlight reading a health report on a tablet, happy and relaxed."),
  23. (3, 0, "hero-background", "right-half",
  24. "A family silhouette connected to floating digital health service icons (heart, pulse line, shield) via soft glowing threads, warm orange light."),
  25. (4, 0, "inline-illustration", "inline",
  26. "Scattered fragmented data puzzle pieces with a heart shape slowly emerging from the fragments."),
  27. (5, 0, "inline-illustration", "inline",
  28. "A parent holding a smartphone managing family health tasks, floating checklists and heart icons around the phone."),
  29. (6, 2, "inline-illustration", "inline",
  30. "AI agent service architecture: a friendly robot connected to a glowing knowledge base and data streams."),
  31. (8, 0, "hero-background", "right-half",
  32. "National policy documents and rising technology trend curves converging into a bright future gateway, tech blue tones."),
  33. (10, 1, "inline-illustration", "inline",
  34. "A confused parent looking at a thick professional medical report full of complex charts they cannot understand."),
  35. (11, 0, "hero-background", "right-half",
  36. "A soaring upward growth curve over a vast open city skyline, representing a trillion-yuan market opportunity, blue and orange tones."),
  37. (13, 2, "inline-illustration", "inline",
  38. "Competitive landscape map with one distinctive position highlighted by a warm orange beacon among blue competitors."),
  39. (14, 2, "inline-illustration", "inline",
  40. "Three-sided marketplace: families, planners, and activity providers connected by a glowing triangle platform."),
  41. (15, 0, "hero-background", "right-half",
  42. "Five-element energy system: five colored energy orbs (orange, pink, indigo, green, gold) circulating in a harmonious ring, warm orange dominant."),
  43. (16, 0, "inline-illustration", "inline",
  44. "Fragmented family health data scattered across devices (phone, tablet, paper reports) with disconnected wires, pain point mood."),
  45. (17, 1, "inline-illustration", "inline",
  46. "A five-dimensional energy dashboard sandbox: circular gauges with five colored energy rings glowing softly."),
  47. (18, 1, "inline-illustration", "inline",
  48. "A family health data flywheel loop: data, analysis, plan, action, improvement rotating in a continuous glowing cycle."),
  49. (19, 0, "hero-background", "right-half",
  50. "A glowing shield protecting flowing data streams, representing technology and data moats, tech navy blue dominant."),
  51. (20, 2, "inline-illustration", "inline",
  52. "Five-element mutual generation and restriction: five colored circles connected by curved arrows in dynamic balance."),
  53. (21, 0, "inline-illustration", "inline",
  54. "An AI health advisor avatar gently connecting to family data points floating around a home."),
  55. (22, 1, "inline-illustration", "inline",
  56. "Three-party network flywheel: families, planners, partners spinning together in a growing wheel."),
  57. (23, 0, "hero-background", "right-half",
  58. "Real achievements: a certificate of growth results with an upward progress curve and warm orange and blue tones."),
  59. (24, 1, "inline-illustration", "inline",
  60. "AI extracting key metrics from a thick report: a magnifying glass over dense pages revealing bright glowing key indicators."),
  61. (25, 0, "inline-illustration", "inline",
  62. "Authoritative academic institution endorsement: a laurel wreath and seal over a rising chart, trustworthy mood."),
  63. (26, 2, "hero-background", "full-bleed",
  64. "Warm family silhouettes walking toward an ascending path of light, echoing the cover, warm orange and blue tones."),
  65. ]
  66. def generate_one(idx, slide, card, usage, placement, desc):
  67. prompt = desc + " " + COMPOSITION[placement] + " " + STYLE
  68. body = json.dumps({"model": MODEL, "prompt": prompt, "size": "1024x1024", "n": 1}).encode("utf-8")
  69. req = urllib.request.Request(API_URL, data=body, headers={
  70. "Content-Type": "application/json",
  71. "Authorization": "Bearer " + TOKEN,
  72. })
  73. with urllib.request.urlopen(req, timeout=120) as resp:
  74. data = json.loads(resp.read().decode("utf-8"))
  75. url = data["data"][0]["url"]
  76. fname = os.path.join(OUT_DIR, f"slide_{slide:02d}_{card}.png")
  77. urllib.request.urlretrieve(url, fname)
  78. return fname
  79. def main():
  80. todo = []
  81. for slide, card, usage, placement, desc in IMAGES:
  82. fname = os.path.join(OUT_DIR, f"slide_{slide:02d}_{card}.png")
  83. if os.path.exists(fname) and os.path.getsize(fname) > 1024:
  84. print(f"[skip] {fname} exists")
  85. continue
  86. todo.append((slide, card, usage, placement, desc))
  87. print(f"[todo] {len(todo)} images to generate")
  88. for idx, (slide, card, usage, placement, desc) in enumerate(todo, 1):
  89. for attempt in range(3):
  90. try:
  91. fname = generate_one(idx, slide, card, usage, placement, desc)
  92. print(f"[{idx}/{len(todo)}] OK slide_{slide:02d}_{card}.png ({os.path.getsize(fname)} bytes)")
  93. break
  94. except Exception as e:
  95. print(f"[{idx}/{len(todo)}] slide_{slide:02d}_{card} attempt {attempt+1} failed: {e}")
  96. time.sleep(5)
  97. else:
  98. print(f"[{idx}/{len(todo)}] FAILED slide_{slide:02d}_{card} after 3 attempts")
  99. if __name__ == "__main__":
  100. main()