🎨 Add 54 PNG assets with transparent backgrounds + generation scripts
Assets (54 PNG files with transparent backgrounds): - npcs/: 13 (Gronk, Kai, Ana, trader, blacksmith, healer, hunter, farmer, etc.) - zivali/: 12 (Susi, husky, cow, pig, sheep, horse, wolf, bear, phoenix, unicorn) - bosses/: 8 (T-Rex, Kraken, Dragon, Zombie King, Golem, Spider Queen, etc.) - mutanti/: 5 (zombies, slimes) - items/: 7 (axe, sword, wands, potions, ana_bracelet, gronk_vape) - environment/: 5 (tree, campfire, chest, rock, bush) Scripts added: - generate_v7_final.py: Google Imagen API generator - generate_comfyui_transparent.py: ComfyUI with auto transparency - generate_local_final.py: ComfyUI + rembg background removal - generate_background.py: Asset registry and queue manager Style: 2D Indie Cartoon Vector with clean lines, full body, tight crop All backgrounds removed with rembg for transparent PNG output
BIN
assets/images/bosses/boss_dragon_fire.png
Normal file
|
After Width: | Height: | Size: 860 KiB |
BIN
assets/images/bosses/boss_golem.png
Normal file
|
After Width: | Height: | Size: 769 KiB |
BIN
assets/images/bosses/boss_kraken.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/images/bosses/boss_slime_emperor.png
Normal file
|
After Width: | Height: | Size: 563 KiB |
BIN
assets/images/bosses/boss_spider_queen.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
assets/images/bosses/boss_trex.png
Normal file
|
After Width: | Height: | Size: 641 KiB |
BIN
assets/images/bosses/boss_werewolf.png
Normal file
|
After Width: | Height: | Size: 834 KiB |
BIN
assets/images/bosses/boss_zombie_king.png
Normal file
|
After Width: | Height: | Size: 876 KiB |
BIN
assets/images/environment/bush_green.png
Normal file
|
After Width: | Height: | Size: 687 KiB |
BIN
assets/images/environment/campfire.png
Normal file
|
After Width: | Height: | Size: 509 KiB |
BIN
assets/images/environment/chest_wooden.png
Normal file
|
After Width: | Height: | Size: 650 KiB |
BIN
assets/images/environment/rock_large.png
Normal file
|
After Width: | Height: | Size: 812 KiB |
BIN
assets/images/environment/tree_oak.png
Normal file
|
After Width: | Height: | Size: 700 KiB |
BIN
assets/images/items/ana_bracelet.png
Normal file
|
After Width: | Height: | Size: 501 KiB |
BIN
assets/images/items/gronk_vape.png
Normal file
|
After Width: | Height: | Size: 562 KiB |
BIN
assets/images/items/potion_health.png
Normal file
|
After Width: | Height: | Size: 421 KiB |
BIN
assets/images/items/tool_axe_iron.png
Normal file
|
After Width: | Height: | Size: 365 KiB |
BIN
assets/images/items/wand_fire.png
Normal file
|
After Width: | Height: | Size: 267 KiB |
BIN
assets/images/items/wand_ice.png
Normal file
|
After Width: | Height: | Size: 338 KiB |
BIN
assets/images/items/weapon_sword_iron.png
Normal file
|
After Width: | Height: | Size: 312 KiB |
BIN
assets/images/mutanti/slime_blue.png
Normal file
|
After Width: | Height: | Size: 483 KiB |
BIN
assets/images/mutanti/slime_green.png
Normal file
|
After Width: | Height: | Size: 385 KiB |
BIN
assets/images/mutanti/zombie_basic.png
Normal file
|
After Width: | Height: | Size: 297 KiB |
BIN
assets/images/mutanti/zombie_dreadlocks.png
Normal file
|
After Width: | Height: | Size: 512 KiB |
BIN
assets/images/mutanti/zombie_runner.png
Normal file
|
After Width: | Height: | Size: 485 KiB |
BIN
assets/images/npcs/ana_explorer.png
Normal file
|
After Width: | Height: | Size: 440 KiB |
BIN
assets/images/npcs/gronk_front_walk1.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
assets/images/npcs/gronk_front_walk2.png
Normal file
|
After Width: | Height: | Size: 155 KiB |
BIN
assets/images/npcs/gronk_troll.png
Normal file
|
After Width: | Height: | Size: 797 KiB |
BIN
assets/images/npcs/kai_survivor.png
Normal file
|
After Width: | Height: | Size: 457 KiB |
BIN
assets/images/npcs/npc_blacksmith.png
Normal file
|
After Width: | Height: | Size: 507 KiB |
BIN
assets/images/npcs/npc_child.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
assets/images/npcs/npc_cook.png
Normal file
|
After Width: | Height: | Size: 138 KiB |
BIN
assets/images/npcs/npc_elder.png
Normal file
|
After Width: | Height: | Size: 155 KiB |
BIN
assets/images/npcs/npc_farmer.png
Normal file
|
After Width: | Height: | Size: 513 KiB |
BIN
assets/images/npcs/npc_healer.png
Normal file
|
After Width: | Height: | Size: 573 KiB |
BIN
assets/images/npcs/npc_hunter.png
Normal file
|
After Width: | Height: | Size: 637 KiB |
BIN
assets/images/npcs/npc_mechanic.png
Normal file
|
After Width: | Height: | Size: 455 KiB |
BIN
assets/images/npcs/npc_medic.png
Normal file
|
After Width: | Height: | Size: 333 KiB |
BIN
assets/images/npcs/npc_scout.png
Normal file
|
After Width: | Height: | Size: 238 KiB |
BIN
assets/images/npcs/npc_soldier.png
Normal file
|
After Width: | Height: | Size: 453 KiB |
BIN
assets/images/npcs/npc_trader.png
Normal file
|
After Width: | Height: | Size: 830 KiB |
BIN
assets/images/zivali/bear_brown.png
Normal file
|
After Width: | Height: | Size: 565 KiB |
BIN
assets/images/zivali/cat_tabby.png
Normal file
|
After Width: | Height: | Size: 574 KiB |
BIN
assets/images/zivali/chicken_white.png
Normal file
|
After Width: | Height: | Size: 435 KiB |
BIN
assets/images/zivali/cow_spotted.png
Normal file
|
After Width: | Height: | Size: 488 KiB |
BIN
assets/images/zivali/dog_husky.png
Normal file
|
After Width: | Height: | Size: 685 KiB |
BIN
assets/images/zivali/horse_brown.png
Normal file
|
After Width: | Height: | Size: 464 KiB |
BIN
assets/images/zivali/phoenix_chicken.png
Normal file
|
After Width: | Height: | Size: 502 KiB |
BIN
assets/images/zivali/pig_pink.png
Normal file
|
After Width: | Height: | Size: 480 KiB |
BIN
assets/images/zivali/sheep_fluffy.png
Normal file
|
After Width: | Height: | Size: 456 KiB |
BIN
assets/images/zivali/susi_dachshund.png
Normal file
|
After Width: | Height: | Size: 300 KiB |
BIN
assets/images/zivali/unicorn.png
Normal file
|
After Width: | Height: | Size: 470 KiB |
BIN
assets/images/zivali/wolf_grey.png
Normal file
|
After Width: | Height: | Size: 574 KiB |
200
scripts/generate_background.py
Normal file
@@ -0,0 +1,200 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🎮 DOLINA SMRTI - Background Asset Generator
|
||||
Runs unattended, generates remaining assets with transparent backgrounds
|
||||
Uses Google Imagen + rembg for transparent PNG output
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# Paths
|
||||
ARTIFACTS = Path("/Users/davidkotnik/.gemini/antigravity/brain/1359204e-4aaa-41ba-abbf-9b1bab2caa00")
|
||||
OUTPUT = Path("/Users/davidkotnik/repos/novafarma/assets/images")
|
||||
|
||||
# Style prefix for all assets
|
||||
STYLE = "2D indie game sprite, cartoon vector style, clean smooth lines, full body visible, tight crop minimal padding, PNG game asset"
|
||||
|
||||
# ============================================================================
|
||||
# COMPLETE ASSET REGISTRY
|
||||
# ============================================================================
|
||||
|
||||
ASSETS = [
|
||||
# NPCs - remaining
|
||||
("npcs", "npc_mechanic", "mechanic survivor, oil stained clothes, wrench, welding goggles"),
|
||||
("npcs", "npc_soldier", "ex-military survivor, tactical vest, rifle, scarred face"),
|
||||
("npcs", "npc_medic", "field medic, white coat with blood stains, medical bag"),
|
||||
("npcs", "npc_elder", "wise tribal elder, walking stick, long white beard"),
|
||||
("npcs", "npc_child", "survivor orphan child, oversized clothes, teddy bear"),
|
||||
("npcs", "npc_cook", "camp cook, pot and ladle, big belly, friendly"),
|
||||
("npcs", "npc_scout", "nomad scout, binoculars, light armor, agile"),
|
||||
|
||||
# Animation frames for main characters
|
||||
("npcs", "gronk_front_walk1", "Gronk troll, PINK dreadlocks, black baggy shirt, front facing, walking animation frame 1"),
|
||||
("npcs", "gronk_front_walk2", "Gronk troll, PINK dreadlocks, black baggy shirt, front facing, walking animation frame 2"),
|
||||
("npcs", "gronk_back_walk1", "Gronk troll, PINK dreadlocks, black baggy shirt, back view, walking animation"),
|
||||
("npcs", "kai_front_walk1", "Kai survivor, GREEN dreadlocks, blue jacket, front facing, walking animation frame 1"),
|
||||
("npcs", "kai_front_walk2", "Kai survivor, GREEN dreadlocks, blue jacket, front facing, walking animation frame 2"),
|
||||
("npcs", "kai_back_walk1", "Kai survivor, GREEN dreadlocks, blue jacket, back view, walking animation"),
|
||||
("npcs", "ana_front_walk1", "Ana explorer, PINK dreadlocks, brown vest, front facing, walking animation frame 1"),
|
||||
("npcs", "ana_front_walk2", "Ana explorer, PINK dreadlocks, brown vest, front facing, walking animation frame 2"),
|
||||
|
||||
# More animals
|
||||
("zivali", "pig_pink", "pink pig, curly tail, muddy, happy, farm animal"),
|
||||
("zivali", "sheep_fluffy", "white fluffy sheep, wool, cute, farm animal"),
|
||||
("zivali", "goat_brown", "brown goat, small horns, playful"),
|
||||
("zivali", "horse_brown", "brown horse, black mane, majestic"),
|
||||
("zivali", "rabbit_white", "white rabbit, long ears, fluffy"),
|
||||
("zivali", "wolf_grey", "grey wolf, fierce, pack hunter, wildlife"),
|
||||
("zivali", "bear_brown", "brown bear, large, powerful, wildlife"),
|
||||
("zivali", "fox_red", "red fox, bushy tail, clever, wildlife"),
|
||||
("zivali", "golden_goose", "Golden Goose, shimmering gold feathers, legendary"),
|
||||
("zivali", "fire_sheep", "Fire Sheep, burning wool flames, magical mutant"),
|
||||
|
||||
# More mutants
|
||||
("mutanti", "slime_red", "red fire slime monster, hot, flames"),
|
||||
("mutanti", "slime_purple", "purple poison slime, toxic, bubbling"),
|
||||
("mutanti", "mutant_dog", "mutant dog, hairless, sores, vicious"),
|
||||
("mutanti", "mutant_rat_giant", "giant rat mutant, dog sized, diseased"),
|
||||
("mutanti", "mutant_spider", "giant spider, eight legs, web, terrifying"),
|
||||
("mutanti", "zombie_bloated", "bloated zombie, huge swollen, toxic green drool"),
|
||||
("mutanti", "zombie_armored", "armored zombie, riot gear, tough, slow"),
|
||||
("mutanti", "zombie_crawler", "crawler zombie, no legs, crawling desperately"),
|
||||
|
||||
# More bosses
|
||||
("bosses", "boss_slime_emperor", "Slime Emperor, gigantic rainbow slime, crown, bouncing"),
|
||||
("bosses", "boss_dragon_ice", "Ice Dragon, blue scales, frost breath, majestic"),
|
||||
("bosses", "boss_spider_queen", "Spider Queen, giant spider, egg sacs, web lair"),
|
||||
("bosses", "boss_werewolf", "Werewolf Alpha, massive wolf-human hybrid, moonlight"),
|
||||
("bosses", "boss_vampire", "Vampire Lord, ancient, cape, fangs, pale"),
|
||||
("bosses", "boss_phoenix", "Phoenix boss, giant fire bird, rebirth"),
|
||||
("bosses", "boss_hydra", "Hydra, multi-headed serpent, regenerating"),
|
||||
("bosses", "boss_golem", "Stone Golem, massive rock creature, ancient"),
|
||||
("bosses", "boss_treant", "Elder Treant, giant living tree, nature guardian"),
|
||||
("bosses", "boss_demon", "Demon Prince, hellfire, horns, terrifying"),
|
||||
|
||||
# More items
|
||||
("items", "tool_pickaxe_iron", "iron pickaxe, mining tool, wooden handle"),
|
||||
("items", "tool_shovel", "shovel, digging tool, wooden handle"),
|
||||
("items", "tool_hammer", "hammer, building tool"),
|
||||
("items", "weapon_bow_wood", "wooden bow with arrows"),
|
||||
("items", "weapon_spear", "wooden spear, hunting weapon"),
|
||||
("items", "weapon_crossbow", "crossbow, powerful ranged"),
|
||||
("items", "wand_lightning", "lightning magic wand, yellow crystal, sparks"),
|
||||
("items", "wand_earth", "earth magic wand, green crystal, nature"),
|
||||
("items", "wand_shadow", "shadow magic wand, purple crystal, darkness"),
|
||||
("items", "wand_healing", "healing wand, white crystal, glow"),
|
||||
("items", "potion_mana", "mana potion, blue liquid bottle"),
|
||||
("items", "backpack_small", "small leather backpack"),
|
||||
("items", "backpack_large", "large hiking backpack"),
|
||||
("items", "helmet_metal", "metal protective helmet"),
|
||||
("items", "gas_mask", "gas mask, protection, filters"),
|
||||
("items", "food_bread", "bread loaf, fresh baked"),
|
||||
("items", "food_apple", "red apple, fresh fruit"),
|
||||
("items", "food_meat", "cooked meat, steak"),
|
||||
|
||||
# More environment
|
||||
("environment", "tree_pine", "pine tree, evergreen, cone shaped"),
|
||||
("environment", "tree_dead", "dead tree, no leaves, gnarled"),
|
||||
("environment", "tree_cherry", "cherry blossom tree, pink flowers"),
|
||||
("environment", "flower_red", "red flowers patch"),
|
||||
("environment", "flower_blue", "blue flowers patch"),
|
||||
("environment", "mushroom_brown", "brown mushrooms cluster"),
|
||||
("environment", "mushroom_red", "red spotted mushrooms"),
|
||||
("environment", "fence_wood", "wooden fence section"),
|
||||
("environment", "gate_wood", "wooden gate"),
|
||||
("environment", "bridge_wood", "wooden bridge section"),
|
||||
("environment", "barrel_wood", "wooden barrel, storage"),
|
||||
("environment", "crate_wooden", "wooden shipping crate"),
|
||||
("environment", "ruin_wall", "ruined brick wall section"),
|
||||
("environment", "car_rusted", "rusted abandoned car"),
|
||||
("environment", "sign_warning", "warning sign post"),
|
||||
|
||||
# Tiles (32x32)
|
||||
("environment", "tile_grass_green", "green grass ground tile, 32x32 seamless texture"),
|
||||
("environment", "tile_grass_dry", "dry brown grass tile, 32x32 seamless texture"),
|
||||
("environment", "tile_dirt_brown", "brown dirt path tile, 32x32 seamless texture"),
|
||||
("environment", "tile_sand_yellow", "yellow sand beach tile, 32x32 seamless texture"),
|
||||
("environment", "tile_snow_white", "white snow tile, 32x32 seamless texture"),
|
||||
("environment", "tile_water_shallow", "shallow blue water tile, 32x32 seamless texture"),
|
||||
("environment", "tile_stone_grey", "grey stone floor tile, 32x32 seamless texture"),
|
||||
|
||||
# UI
|
||||
("ui", "ui_health_bar", "health bar UI, red hearts row"),
|
||||
("ui", "ui_energy_bar", "energy bar UI, green lightning"),
|
||||
("ui", "ui_inventory_slot", "inventory slot UI, wooden frame"),
|
||||
("ui", "ui_button_menu", "menu button UI, wooden, round"),
|
||||
("ui", "ui_cursor_hand", "hand cursor pointer"),
|
||||
("ui", "ui_icon_gold", "gold coin icon"),
|
||||
]
|
||||
|
||||
|
||||
def log(msg):
|
||||
"""Log with timestamp"""
|
||||
ts = datetime.now().strftime("%H:%M:%S")
|
||||
print(f"[{ts}] {msg}")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def generate_with_gemini(prompt, name):
|
||||
"""Generate image using Gemini CLI tool"""
|
||||
# This uses the gemini command line if available
|
||||
# Falls back to placeholder for now
|
||||
log(f"⏳ Would generate: {name}")
|
||||
return False
|
||||
|
||||
|
||||
def remove_background(src_path, dst_path):
|
||||
"""Remove background using rembg"""
|
||||
try:
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
|
||||
img = remove(Image.open(src_path))
|
||||
img.save(dst_path, "PNG")
|
||||
return True
|
||||
except Exception as e:
|
||||
log(f"❌ rembg error: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
log("=" * 60)
|
||||
log("🎮 DOLINA SMRTI - Background Asset Generator")
|
||||
log("=" * 60)
|
||||
|
||||
# Get already generated
|
||||
existing = set()
|
||||
for cat in ["npcs", "zivali", "mutanti", "bosses", "items", "environment", "ui"]:
|
||||
cat_dir = OUTPUT / cat
|
||||
if cat_dir.exists():
|
||||
for f in cat_dir.glob("*.png"):
|
||||
existing.add(f.stem)
|
||||
|
||||
log(f"📊 Existing: {len(existing)} | Total: {len(ASSETS)}")
|
||||
|
||||
remaining = [(c, n, p) for c, n, p in ASSETS if n not in existing]
|
||||
log(f"🎯 To generate: {len(remaining)}")
|
||||
|
||||
if not remaining:
|
||||
log("✅ All assets already generated!")
|
||||
return
|
||||
|
||||
log("\n📋 Queue:")
|
||||
for cat, name, _ in remaining[:10]:
|
||||
log(f" - {cat}/{name}")
|
||||
if len(remaining) > 10:
|
||||
log(f" ... and {len(remaining) - 10} more")
|
||||
|
||||
log("\n⚠️ Manual generation required:")
|
||||
log(" This script shows the queue.")
|
||||
log(" Use the Gemini generate_image tool interactively.")
|
||||
log("\n✅ Script complete - see queue above")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
349
scripts/generate_comfyui_transparent.py
Normal file
@@ -0,0 +1,349 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🎮 DOLINA SMRTI - ComfyUI Local Generator
|
||||
Transparent Background (Alpha Channel)
|
||||
2D Indie Cartoon Style - Approved Gronk/Kai look
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
import requests
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
import io
|
||||
|
||||
# Configuration
|
||||
COMFYUI_URL = "http://127.0.0.1:8000"
|
||||
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
|
||||
|
||||
# ============================================================================
|
||||
# STYLE DEFINITIONS - Approved 2D Indie Cartoon
|
||||
# ============================================================================
|
||||
|
||||
STYLE_PREFIX = """2D indie game sprite, cartoon vector style, clean smooth lines,
|
||||
full body visible from head to feet standing on ground,
|
||||
tight crop max 5 pixel padding around subject, """
|
||||
|
||||
STYLE_SUFFIX = """, isolated on pure white background #FFFFFF, game asset"""
|
||||
|
||||
NEGATIVE_PROMPT = """pixel art, pixelated, voxel, 3d render, realistic photo,
|
||||
anime, manga, chibi, floating, cut off, cropped, blurry, low quality,
|
||||
watermark, text, signature, green background, colored background"""
|
||||
|
||||
# ============================================================================
|
||||
# MASTER REGISTRY
|
||||
# ============================================================================
|
||||
|
||||
def generate_registry():
|
||||
"""Generate complete asset registry"""
|
||||
assets = []
|
||||
|
||||
# Main Characters
|
||||
gronk = """Gronk the troll, massive green-grey skinned troll, PINK dreadlocks,
|
||||
stretched earlobes with large gauges, facial piercings, holding colorful vape device with pink smoke,
|
||||
wearing LOOSE BAGGY black t-shirt with band logo, LOOSE WIDE black pants, pink sneakers,
|
||||
peaceful zen expression"""
|
||||
|
||||
kai = """Kai teenage boy survivor, post-apocalyptic nomad style, GREEN natural dreadlocks hair,
|
||||
stretched earlobes with plugs, facial piercings on nose and lip, wearing dirty worn blue jacket,
|
||||
torn jeans, combat boots, survival backpack, determined serious expression, athletic build"""
|
||||
|
||||
ana = """Ana teenage girl explorer, PINK dreadlocks hair, stretched earlobes with small plugs,
|
||||
wearing brown adventure vest over green shirt, blue jeans, brown hiking boots,
|
||||
leather backpack with map, kind curious expression"""
|
||||
|
||||
main_chars = [
|
||||
("gronk_troll", gronk),
|
||||
("kai_survivor", kai),
|
||||
("ana_explorer", ana),
|
||||
]
|
||||
|
||||
for name, desc in main_chars:
|
||||
assets.append({"cat": "npcs", "file": f"{name}.png", "prompt": desc})
|
||||
for d in ["front", "back", "left", "right"]:
|
||||
for a in ["idle", "walk1", "walk2"]:
|
||||
assets.append({
|
||||
"cat": "npcs",
|
||||
"file": f"{name}_{d}_{a}.png",
|
||||
"prompt": f"{desc}, {d} facing view, {a} animation frame"
|
||||
})
|
||||
|
||||
# NPCs
|
||||
npcs = [
|
||||
("npc_trader", "wasteland trader, nomadic merchant with cart, weathered face, hooded cloak"),
|
||||
("npc_blacksmith", "nomadic blacksmith, leather apron, strong arms, hammer"),
|
||||
("npc_healer", "herbalist healer woman, herb pouch, kind elderly, flower crown"),
|
||||
("npc_hunter", "wasteland hunter, crossbow, animal pelts, face paint"),
|
||||
("npc_farmer", "apocalypse farmer, patched overalls, straw hat, hoe"),
|
||||
]
|
||||
|
||||
for name, desc in npcs:
|
||||
assets.append({"cat": "npcs", "file": f"{name}.png", "prompt": desc})
|
||||
|
||||
# Animals
|
||||
animals = [
|
||||
("susi_dachshund", "Susi dachshund dog, brown and black, long body, floppy ears, pink collar"),
|
||||
("dog_husky", "husky dog, fluffy grey white, blue eyes, friendly"),
|
||||
("cat_tabby", "orange tabby cat, striped, lazy curious"),
|
||||
("cow_spotted", "dairy cow, black white spots, friendly"),
|
||||
("chicken_white", "white chicken, red comb, pecking"),
|
||||
("phoenix_chicken", "Phoenix Chicken, fire feathers, glowing orange-red, legendary"),
|
||||
("unicorn", "magical Unicorn, white horse, rainbow mane, golden spiral horn"),
|
||||
]
|
||||
|
||||
for name, desc in animals:
|
||||
assets.append({"cat": "zivali", "file": f"{name}.png", "prompt": desc})
|
||||
|
||||
# Mutants
|
||||
mutants = [
|
||||
("zombie_basic", "basic zombie, shambling, torn clothes, grey-green skin, undead"),
|
||||
("zombie_runner", "fast zombie, sprinting, aggressive, rage face"),
|
||||
("zombie_dreadlocks", "zombie with dreadlocks, brown shirt, farmer style"),
|
||||
("slime_green", "green slime monster, bouncy blob, cute-creepy, small eyes"),
|
||||
("slime_blue", "blue slime, water element, wobbly, transparent"),
|
||||
]
|
||||
|
||||
for name, desc in mutants:
|
||||
assets.append({"cat": "mutanti", "file": f"{name}.png", "prompt": desc})
|
||||
|
||||
# Bosses
|
||||
bosses = [
|
||||
("boss_trex", "T-Rex dinosaur boss, massive predator, huge jaws, fierce"),
|
||||
("boss_kraken", "Kraken sea monster, giant octopus, many tentacles"),
|
||||
("boss_zombie_king", "Zombie King, massive undead, rotting crown"),
|
||||
("boss_slime_emperor", "Slime Emperor, gigantic rainbow slime, crown"),
|
||||
("boss_dragon_fire", "Fire Dragon, red scales, breathing flames, wings"),
|
||||
]
|
||||
|
||||
for name, desc in bosses:
|
||||
assets.append({"cat": "bosses", "file": f"{name}.png", "prompt": desc})
|
||||
|
||||
# Items
|
||||
items = [
|
||||
("tool_axe_iron", "iron axe, chopping tool, wooden handle"),
|
||||
("tool_pickaxe_iron", "iron pickaxe, mining tool"),
|
||||
("weapon_sword_iron", "iron sword, combat blade"),
|
||||
("weapon_bow_wood", "wooden bow with arrows"),
|
||||
("wand_fire", "fire magic wand, red crystal tip, flames"),
|
||||
("wand_ice", "ice magic wand, blue crystal, frost"),
|
||||
("ana_bracelet", "Ana's magical bracelet, glowing, family heirloom"),
|
||||
("gronk_vape", "Gronk's golden vape device, colorful, smoking"),
|
||||
("potion_health", "health potion, red liquid bottle"),
|
||||
("food_bread", "bread loaf, fresh baked"),
|
||||
]
|
||||
|
||||
for name, desc in items:
|
||||
assets.append({"cat": "items", "file": f"{name}.png", "prompt": desc})
|
||||
|
||||
# Environment
|
||||
tiles = [
|
||||
("tile_grass_green", "green grass ground tile, 32x32 seamless"),
|
||||
("tile_dirt_brown", "brown dirt path tile, 32x32 seamless"),
|
||||
("tile_water_shallow", "shallow blue water tile, 32x32 seamless"),
|
||||
("tile_stone_grey", "grey stone floor tile, 32x32 seamless"),
|
||||
]
|
||||
|
||||
objects = [
|
||||
("tree_oak", "oak tree, green leaves, brown trunk"),
|
||||
("tree_dead", "dead tree, no leaves, gnarled branches"),
|
||||
("rock_large", "large boulder, moss covered"),
|
||||
("bush_green", "green bush, leafy"),
|
||||
("campfire", "campfire, flames, logs"),
|
||||
("chest_wooden", "wooden treasure chest, closed"),
|
||||
]
|
||||
|
||||
for name, desc in tiles + objects:
|
||||
assets.append({"cat": "environment", "file": f"{name}.png", "prompt": desc})
|
||||
|
||||
return assets
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# COMFYUI WORKFLOW - With Background Removal
|
||||
# ============================================================================
|
||||
|
||||
def create_workflow(prompt_text: str, output_name: str, size: int = 512) -> dict:
|
||||
"""Creates ComfyUI workflow with white background for easy removal"""
|
||||
seed = int(time.time() * 1000) % 2147483647
|
||||
full_prompt = STYLE_PREFIX + prompt_text + STYLE_SUFFIX
|
||||
|
||||
return {
|
||||
"1": {
|
||||
"class_type": "CheckpointLoaderSimple",
|
||||
"inputs": {"ckpt_name": "dreamshaper_8.safetensors"}
|
||||
},
|
||||
"2": {
|
||||
"class_type": "EmptyLatentImage",
|
||||
"inputs": {"width": size, "height": size, "batch_size": 1}
|
||||
},
|
||||
"3": {
|
||||
"class_type": "CLIPTextEncode",
|
||||
"inputs": {"text": full_prompt, "clip": ["1", 1]}
|
||||
},
|
||||
"4": {
|
||||
"class_type": "CLIPTextEncode",
|
||||
"inputs": {"text": NEGATIVE_PROMPT, "clip": ["1", 1]}
|
||||
},
|
||||
"5": {
|
||||
"class_type": "KSampler",
|
||||
"inputs": {
|
||||
"seed": seed,
|
||||
"steps": 30,
|
||||
"cfg": 7.5,
|
||||
"sampler_name": "euler_ancestral",
|
||||
"scheduler": "karras",
|
||||
"denoise": 1.0,
|
||||
"model": ["1", 0],
|
||||
"positive": ["3", 0],
|
||||
"negative": ["4", 0],
|
||||
"latent_image": ["2", 0]
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"class_type": "VAEDecode",
|
||||
"inputs": {"samples": ["5", 0], "vae": ["1", 2]}
|
||||
},
|
||||
"7": {
|
||||
"class_type": "SaveImage",
|
||||
"inputs": {"filename_prefix": output_name, "images": ["6", 0]}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def queue_prompt(workflow: dict) -> str:
|
||||
try:
|
||||
r = requests.post(
|
||||
f"{COMFYUI_URL}/prompt",
|
||||
json={"prompt": workflow, "client_id": f"ds_{uuid.uuid4().hex[:8]}"}
|
||||
)
|
||||
return r.json().get("prompt_id")
|
||||
except Exception as e:
|
||||
print(f"Queue error: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def wait_completion(prompt_id: str, timeout: int = 300) -> bool:
|
||||
start = time.time()
|
||||
while time.time() - start < timeout:
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}")
|
||||
data = r.json()
|
||||
if prompt_id in data and data[prompt_id].get("outputs"):
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
time.sleep(2)
|
||||
return False
|
||||
|
||||
|
||||
def download_image(prompt_id: str, output_path: Path) -> bool:
|
||||
try:
|
||||
h = requests.get(f"{COMFYUI_URL}/history/{prompt_id}").json()
|
||||
for out in h.get(prompt_id, {}).get("outputs", {}).values():
|
||||
for img in out.get("images", []):
|
||||
r = requests.get(f"{COMFYUI_URL}/view", params={
|
||||
"filename": img["filename"],
|
||||
"subfolder": img.get("subfolder", ""),
|
||||
"type": "output"
|
||||
})
|
||||
if r.status_code == 200:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Load image and convert white background to transparent
|
||||
img_data = Image.open(io.BytesIO(r.content)).convert("RGBA")
|
||||
datas = img_data.getdata()
|
||||
|
||||
new_data = []
|
||||
for item in datas:
|
||||
# If pixel is white (or near white), make transparent
|
||||
if item[0] > 240 and item[1] > 240 and item[2] > 240:
|
||||
new_data.append((255, 255, 255, 0)) # Transparent
|
||||
else:
|
||||
new_data.append(item)
|
||||
|
||||
img_data.putdata(new_data)
|
||||
img_data.save(str(output_path), "PNG")
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Download error: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 70)
|
||||
print("🎮 DOLINA SMRTI - ComfyUI Local Generator")
|
||||
print(" 2D Indie Cartoon Style | Transparent Background")
|
||||
print("=" * 70)
|
||||
|
||||
# Check ComfyUI
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5)
|
||||
v = r.json()["system"]["comfyui_version"]
|
||||
print(f"✅ ComfyUI v{v} running on port 8000")
|
||||
except:
|
||||
print("❌ ComfyUI not running!")
|
||||
print(" Start with: open /Applications/ComfyUI.app")
|
||||
return
|
||||
|
||||
# Build registry
|
||||
print("\n📋 Building asset registry...")
|
||||
ASSETS = generate_registry()
|
||||
print(f"📊 Total: {len(ASSETS)} assets")
|
||||
|
||||
cats = {}
|
||||
for a in ASSETS:
|
||||
cats[a["cat"]] = cats.get(a["cat"], 0) + 1
|
||||
print("\nBreakdown:")
|
||||
for cat, count in sorted(cats.items(), key=lambda x: -x[1]):
|
||||
print(f" {cat}: {count}")
|
||||
|
||||
existing = sum(1 for a in ASSETS if (OUTPUT_DIR / a["cat"] / a["file"]).exists())
|
||||
print(f"\n✅ Exist: {existing} | 🎯 Generate: {len(ASSETS) - existing}")
|
||||
|
||||
print("\n🎮 STARTING GENERATION...\n")
|
||||
|
||||
success, skip, fail = 0, 0, 0
|
||||
|
||||
for i, asset in enumerate(ASSETS, 1):
|
||||
path = OUTPUT_DIR / asset["cat"] / asset["file"]
|
||||
|
||||
if path.exists():
|
||||
skip += 1
|
||||
continue
|
||||
|
||||
print(f"[{i}/{len(ASSETS)}] 🎨 {asset['file'][:40]}...")
|
||||
|
||||
# Determine size
|
||||
size = 512
|
||||
if "tile_" in asset["file"]:
|
||||
size = 256 # Tiles are smaller
|
||||
elif "boss_" in asset["file"]:
|
||||
size = 768 # Bosses are larger
|
||||
|
||||
wf = create_workflow(asset["prompt"], asset["file"].replace(".png", ""), size)
|
||||
pid = queue_prompt(wf)
|
||||
|
||||
if pid and wait_completion(pid) and download_image(pid, path):
|
||||
print(f" ✅ SAVED (transparent)")
|
||||
success += 1
|
||||
else:
|
||||
print(f" ❌ FAILED")
|
||||
fail += 1
|
||||
|
||||
if i % 10 == 0:
|
||||
print(f"\n📊 [{i}/{len(ASSETS)}] ✅{success} ⏭️{skip} ❌{fail}\n")
|
||||
|
||||
time.sleep(0.5)
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("🎮 GENERATION COMPLETE!")
|
||||
print(f"✅ Success: {success} | ⏭️ Skip: {skip} | ❌ Fail: {fail}")
|
||||
print(f"📁 Output: {OUTPUT_DIR}")
|
||||
print("\nAll images have TRANSPARENT backgrounds (alpha channel)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
298
scripts/generate_local_final.py
Normal file
@@ -0,0 +1,298 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🎮 DOLINA SMRTI - ComfyUI Local Generator
|
||||
Generates remaining assets with ComfyUI + rembg for transparent backgrounds
|
||||
No API rate limits!
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
import requests
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# Install rembg on first run if needed
|
||||
try:
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
print("Installing dependencies...")
|
||||
os.system("pip3 install --user rembg pillow onnxruntime")
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
|
||||
# Configuration
|
||||
COMFYUI_URL = "http://127.0.0.1:8000"
|
||||
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
|
||||
COMFYUI_OUTPUT = Path("/Users/davidkotnik/comfyui/output")
|
||||
|
||||
# Style - matches the 2D Indie Cartoon style
|
||||
STYLE = "2D indie game sprite, cartoon vector style, clean smooth lines, full body visible from head to feet standing on ground, tight crop, isolated on pure white background #FFFFFF"
|
||||
NEGATIVE = "pixel art, pixelated, voxel, 3d, realistic, photo, anime, manga, chibi, blurry, watermark, text, green background"
|
||||
|
||||
# ============================================================================
|
||||
# REMAINING ASSETS TO GENERATE
|
||||
# ============================================================================
|
||||
|
||||
ASSETS = [
|
||||
# Remaining NPCs
|
||||
("npcs", "npc_elder", "wise tribal elder NPC, walking stick, long white beard, robes"),
|
||||
("npcs", "npc_child", "survivor orphan child NPC, oversized clothes, teddy bear"),
|
||||
("npcs", "npc_cook", "camp cook NPC, pot and ladle, apron, big belly, friendly"),
|
||||
("npcs", "npc_scout", "nomad scout NPC, binoculars, light leather armor, agile"),
|
||||
|
||||
# Animation frames
|
||||
("npcs", "gronk_front_walk1", "Gronk troll, PINK dreadlocks, black baggy shirt pants, front view, left leg forward walking"),
|
||||
("npcs", "gronk_front_walk2", "Gronk troll, PINK dreadlocks, black baggy shirt pants, front view, right leg forward walking"),
|
||||
("npcs", "gronk_back_idle", "Gronk troll, PINK dreadlocks, black baggy shirt pants, back view, standing idle"),
|
||||
("npcs", "kai_front_walk1", "Kai survivor, GREEN dreadlocks, blue jacket, front view, left leg forward walking"),
|
||||
("npcs", "kai_front_walk2", "Kai survivor, GREEN dreadlocks, blue jacket, front view, right leg forward walking"),
|
||||
("npcs", "kai_back_idle", "Kai survivor, GREEN dreadlocks, blue jacket, back view, standing idle"),
|
||||
("npcs", "ana_front_walk1", "Ana explorer, PINK dreadlocks, brown vest, front view, left leg forward walking"),
|
||||
("npcs", "ana_front_walk2", "Ana explorer, PINK dreadlocks, brown vest, front view, right leg forward walking"),
|
||||
|
||||
# Remaining animals
|
||||
("zivali", "goat_brown", "brown goat farm animal, small horns, playful"),
|
||||
("zivali", "rabbit_white", "white rabbit, long ears, fluffy"),
|
||||
("zivali", "fox_red", "red fox wildlife, bushy tail, clever"),
|
||||
("zivali", "golden_goose", "Golden Goose legendary, shimmering gold feathers"),
|
||||
|
||||
# Remaining mutants
|
||||
("mutanti", "slime_red", "red fire slime monster, hot flames"),
|
||||
("mutanti", "slime_purple", "purple poison slime, toxic bubbling"),
|
||||
("mutanti", "mutant_rat_giant", "giant rat mutant, dog sized, diseased"),
|
||||
("mutanti", "zombie_bloated", "bloated zombie, huge swollen, toxic drool"),
|
||||
("mutanti", "zombie_armored", "armored zombie, riot gear, tough"),
|
||||
("mutanti", "zombie_crawler", "crawler zombie, no legs, crawling"),
|
||||
|
||||
# Remaining bosses
|
||||
("bosses", "boss_dragon_ice", "Ice Dragon boss, blue scales, frost breath"),
|
||||
("bosses", "boss_phoenix", "Phoenix boss, giant fire bird, rebirth flames"),
|
||||
("bosses", "boss_hydra", "Hydra boss, multi-headed serpent"),
|
||||
("bosses", "boss_treant", "Elder Treant boss, giant living tree, nature"),
|
||||
("bosses", "boss_demon", "Demon Prince boss, hellfire, horns"),
|
||||
|
||||
# Remaining items
|
||||
("items", "tool_pickaxe_iron", "iron pickaxe mining tool"),
|
||||
("items", "tool_shovel", "shovel digging tool"),
|
||||
("items", "tool_hammer", "hammer building tool"),
|
||||
("items", "weapon_bow_wood", "wooden bow with arrows"),
|
||||
("items", "weapon_spear", "wooden spear, hunting weapon"),
|
||||
("items", "weapon_crossbow", "crossbow ranged weapon"),
|
||||
("items", "wand_lightning", "lightning magic wand, yellow crystal, sparks"),
|
||||
("items", "wand_earth", "earth magic wand, green crystal, nature"),
|
||||
("items", "wand_shadow", "shadow magic wand, purple crystal, darkness"),
|
||||
("items", "wand_healing", "healing wand, white crystal, glow"),
|
||||
("items", "potion_mana", "mana potion, blue liquid bottle"),
|
||||
("items", "backpack_small", "small leather backpack"),
|
||||
("items", "helmet_metal", "metal protective helmet"),
|
||||
("items", "gas_mask", "gas mask with filters"),
|
||||
("items", "food_bread", "bread loaf, fresh baked"),
|
||||
("items", "food_apple", "red apple, fresh fruit"),
|
||||
("items", "food_meat", "cooked meat steak"),
|
||||
|
||||
# Remaining environment
|
||||
("environment", "tree_pine", "pine tree, evergreen, cone shaped"),
|
||||
("environment", "tree_dead", "dead tree, no leaves, gnarled branches"),
|
||||
("environment", "tree_cherry", "cherry blossom tree, pink flowers"),
|
||||
("environment", "flower_red", "red flowers patch"),
|
||||
("environment", "flower_blue", "blue flowers patch"),
|
||||
("environment", "mushroom_red", "red spotted mushrooms"),
|
||||
("environment", "fence_wood", "wooden fence section"),
|
||||
("environment", "barrel_wood", "wooden barrel storage"),
|
||||
("environment", "crate_wooden", "wooden shipping crate"),
|
||||
("environment", "ruin_wall", "ruined brick wall section"),
|
||||
("environment", "car_rusted", "rusted abandoned car wreck"),
|
||||
("environment", "sign_warning", "warning sign post"),
|
||||
]
|
||||
|
||||
|
||||
def log(msg):
|
||||
ts = datetime.now().strftime("%H:%M:%S")
|
||||
print(f"[{ts}] {msg}")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def create_workflow(prompt_text, output_name, size=512):
|
||||
"""Create ComfyUI workflow"""
|
||||
seed = int(time.time() * 1000) % 2147483647
|
||||
full_prompt = f"{STYLE}, {prompt_text}"
|
||||
|
||||
return {
|
||||
"1": {
|
||||
"class_type": "CheckpointLoaderSimple",
|
||||
"inputs": {"ckpt_name": "dreamshaper_8.safetensors"}
|
||||
},
|
||||
"2": {
|
||||
"class_type": "EmptyLatentImage",
|
||||
"inputs": {"width": size, "height": size, "batch_size": 1}
|
||||
},
|
||||
"3": {
|
||||
"class_type": "CLIPTextEncode",
|
||||
"inputs": {"text": full_prompt, "clip": ["1", 1]}
|
||||
},
|
||||
"4": {
|
||||
"class_type": "CLIPTextEncode",
|
||||
"inputs": {"text": NEGATIVE, "clip": ["1", 1]}
|
||||
},
|
||||
"5": {
|
||||
"class_type": "KSampler",
|
||||
"inputs": {
|
||||
"seed": seed,
|
||||
"steps": 30,
|
||||
"cfg": 7.5,
|
||||
"sampler_name": "euler_ancestral",
|
||||
"scheduler": "karras",
|
||||
"denoise": 1.0,
|
||||
"model": ["1", 0],
|
||||
"positive": ["3", 0],
|
||||
"negative": ["4", 0],
|
||||
"latent_image": ["2", 0]
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"class_type": "VAEDecode",
|
||||
"inputs": {"samples": ["5", 0], "vae": ["1", 2]}
|
||||
},
|
||||
"7": {
|
||||
"class_type": "SaveImage",
|
||||
"inputs": {"filename_prefix": output_name, "images": ["6", 0]}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def queue_prompt(workflow):
|
||||
try:
|
||||
r = requests.post(
|
||||
f"{COMFYUI_URL}/prompt",
|
||||
json={"prompt": workflow, "client_id": f"ds_{uuid.uuid4().hex[:8]}"},
|
||||
timeout=10
|
||||
)
|
||||
return r.json().get("prompt_id")
|
||||
except Exception as e:
|
||||
log(f"❌ Queue error: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def wait_completion(prompt_id, timeout=120):
|
||||
start = time.time()
|
||||
while time.time() - start < timeout:
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}", timeout=5)
|
||||
data = r.json()
|
||||
if prompt_id in data and data[prompt_id].get("outputs"):
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
time.sleep(2)
|
||||
return False
|
||||
|
||||
|
||||
def download_and_process(prompt_id, output_path):
|
||||
"""Download from ComfyUI and remove background with rembg"""
|
||||
try:
|
||||
h = requests.get(f"{COMFYUI_URL}/history/{prompt_id}").json()
|
||||
for out in h.get(prompt_id, {}).get("outputs", {}).values():
|
||||
for img in out.get("images", []):
|
||||
r = requests.get(f"{COMFYUI_URL}/view", params={
|
||||
"filename": img["filename"],
|
||||
"subfolder": img.get("subfolder", ""),
|
||||
"type": "output"
|
||||
})
|
||||
if r.status_code == 200:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Load and remove background
|
||||
from io import BytesIO
|
||||
src_img = Image.open(BytesIO(r.content))
|
||||
transparent_img = remove(src_img)
|
||||
transparent_img.save(str(output_path), "PNG")
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
log(f"❌ Download error: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
log("=" * 60)
|
||||
log("🎮 DOLINA SMRTI - ComfyUI Local Generator")
|
||||
log(" No API rate limits! All local processing!")
|
||||
log("=" * 60)
|
||||
|
||||
# Check ComfyUI
|
||||
try:
|
||||
r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5)
|
||||
v = r.json()["system"]["comfyui_version"]
|
||||
log(f"✅ ComfyUI v{v} running")
|
||||
except:
|
||||
log("❌ ComfyUI not running! Start it first.")
|
||||
return
|
||||
|
||||
# Get existing files
|
||||
existing = set()
|
||||
for cat, name, _ in ASSETS:
|
||||
path = OUTPUT_DIR / cat / f"{name}.png"
|
||||
if path.exists():
|
||||
existing.add(name)
|
||||
|
||||
remaining = [(c, n, p) for c, n, p in ASSETS if n not in existing]
|
||||
|
||||
log(f"\n📊 Status:")
|
||||
log(f" Total in registry: {len(ASSETS)}")
|
||||
log(f" Already generated: {len(existing)}")
|
||||
log(f" Remaining: {len(remaining)}")
|
||||
|
||||
if not remaining:
|
||||
log("\n✅ All assets already generated!")
|
||||
return
|
||||
|
||||
log(f"\n🚀 Starting generation of {len(remaining)} assets...")
|
||||
log(" Each takes ~15-30 seconds\n")
|
||||
|
||||
success, fail = 0, 0
|
||||
start_time = time.time()
|
||||
|
||||
for i, (cat, name, prompt) in enumerate(remaining, 1):
|
||||
path = OUTPUT_DIR / cat / f"{name}.png"
|
||||
|
||||
log(f"[{i}/{len(remaining)}] 🎨 {name}...")
|
||||
|
||||
# Determine size
|
||||
size = 512
|
||||
if "boss_" in name:
|
||||
size = 768
|
||||
|
||||
wf = create_workflow(prompt, name, size)
|
||||
pid = queue_prompt(wf)
|
||||
|
||||
if pid and wait_completion(pid) and download_and_process(pid, path):
|
||||
log(f" ✅ DONE (transparent)")
|
||||
success += 1
|
||||
else:
|
||||
log(f" ❌ FAILED")
|
||||
fail += 1
|
||||
|
||||
# Progress every 5
|
||||
if i % 5 == 0:
|
||||
elapsed = time.time() - start_time
|
||||
per_asset = elapsed / i
|
||||
remaining_time = per_asset * (len(remaining) - i)
|
||||
log(f"\n📊 Progress: {i}/{len(remaining)} | ✅{success} ❌{fail}")
|
||||
log(f" ETA: {remaining_time/60:.1f} min\n")
|
||||
|
||||
elapsed = time.time() - start_time
|
||||
log("\n" + "=" * 60)
|
||||
log("🎮 GENERATION COMPLETE!")
|
||||
log(f" ✅ Success: {success}")
|
||||
log(f" ❌ Failed: {fail}")
|
||||
log(f" ⏱️ Time: {elapsed/60:.1f} min")
|
||||
log(f" 📁 Output: {OUTPUT_DIR}")
|
||||
log("=" * 60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
469
scripts/generate_v7_final.py
Normal file
@@ -0,0 +1,469 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🎮 DOLINA SMRTI - FINALNI GENERATOR V7.0
|
||||
2D Indie Cartoon Style - Green Chroma-Key Background
|
||||
Approved style based on Gronk/Kai test images
|
||||
9000+ Assets
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
import google.generativeai as genai
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
import io
|
||||
|
||||
# Configuration
|
||||
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
|
||||
GREEN_BG = "solid bright green background RGB(0,255,0) chroma key green screen"
|
||||
|
||||
# Style that worked for Gronk/Kai test images
|
||||
STYLE_PREFIX = """2D indie game character sprite, cartoon vector style, clean lines,
|
||||
full body visible from head to feet standing on ground, """
|
||||
|
||||
STYLE_SUFFIX = f""", {GREEN_BG}, game asset, PNG"""
|
||||
|
||||
# ============================================================================
|
||||
# MASTER REGISTRY - 9000+ ASSETS
|
||||
# ============================================================================
|
||||
|
||||
def generate_registry():
|
||||
"""Generate complete asset registry with approved style"""
|
||||
assets = []
|
||||
|
||||
# ========================================================================
|
||||
# 1. MAIN CHARACTERS (~150 with animations)
|
||||
# ========================================================================
|
||||
|
||||
# GRONK - Approved style
|
||||
gronk_base = """Gronk the troll, massive green-grey skinned troll, PINK dreadlocks,
|
||||
stretched earlobes with large gauges, facial piercings, holding colorful vape device with pink smoke,
|
||||
wearing LOOSE BAGGY black t-shirt with band logo, LOOSE WIDE black pants, pink sneakers,
|
||||
peaceful zen expression"""
|
||||
|
||||
# KAI - Approved style
|
||||
kai_base = """Kai teenage boy survivor, post-apocalyptic nomad style, GREEN natural dreadlocks hair,
|
||||
stretched earlobes with plugs, facial piercings on nose and lip, wearing dirty worn blue jacket,
|
||||
torn jeans, combat boots, survival backpack, determined serious expression, athletic build"""
|
||||
|
||||
# ANA - Twin sister
|
||||
ana_base = """Ana teenage girl explorer, Kai's twin sister, PINK dreadlocks hair,
|
||||
stretched earlobes with small plugs, wearing brown adventure vest over green shirt,
|
||||
blue jeans, brown boots, leather backpack with map, kind curious expression"""
|
||||
|
||||
main_chars = [
|
||||
("gronk_troll", gronk_base),
|
||||
("kai_survivor", kai_base),
|
||||
("ana_explorer", ana_base),
|
||||
]
|
||||
|
||||
# Add base sprites and animations
|
||||
for name, desc in main_chars:
|
||||
assets.append({"cat": "npcs", "file": f"{name}.png", "prompt": desc})
|
||||
|
||||
# 4 directions, animations
|
||||
for direction in ["front", "back", "left", "right"]:
|
||||
for action in ["idle", "walk1", "walk2", "walk3", "walk4"]:
|
||||
assets.append({
|
||||
"cat": "npcs",
|
||||
"file": f"{name}_{direction}_{action}.png",
|
||||
"prompt": f"{desc}, {direction} facing view, {action} animation frame"
|
||||
})
|
||||
# Work animations
|
||||
for work in ["chop", "mine", "dig"]:
|
||||
assets.append({
|
||||
"cat": "npcs",
|
||||
"file": f"{name}_{direction}_{work}.png",
|
||||
"prompt": f"{desc}, {direction} facing, {work}ping with tool animation"
|
||||
})
|
||||
|
||||
# ========================================================================
|
||||
# 2. NPCs - NOMADIC SURVIVORS (~50)
|
||||
# ========================================================================
|
||||
|
||||
npcs = [
|
||||
("npc_trader", "wasteland trader, nomadic merchant with cart, weathered face, hooded cloak"),
|
||||
("npc_blacksmith", "nomadic blacksmith, leather apron, strong arms, hammer, burns"),
|
||||
("npc_healer", "herbalist healer woman, herb pouch, kind elderly, flower crown"),
|
||||
("npc_hunter", "wasteland hunter, crossbow, animal pelts, face paint"),
|
||||
("npc_farmer", "apocalypse farmer, patched overalls, straw hat, hoe"),
|
||||
("npc_mechanic", "mechanic survivor, oil stained, wrench, welding goggles"),
|
||||
("npc_soldier", "ex-military survivor, tactical vest, rifle, scarred"),
|
||||
("npc_medic", "field medic, white coat blood stains, medical bag"),
|
||||
("npc_elder", "wise tribal elder, walking stick, long white beard"),
|
||||
("npc_child", "survivor orphan child, oversized clothes, teddy bear"),
|
||||
("npc_cook", "camp cook, pot and ladle, big belly, friendly"),
|
||||
("npc_scout", "nomad scout, binoculars, light armor, agile"),
|
||||
]
|
||||
|
||||
for name, desc in npcs:
|
||||
assets.append({"cat": "npcs", "file": f"{name}.png", "prompt": f"2D indie game character, {desc}, full body standing"})
|
||||
|
||||
# ========================================================================
|
||||
# 3. ANIMALS - COMPANIONS & WILDLIFE (~100)
|
||||
# ========================================================================
|
||||
|
||||
animals = [
|
||||
# Companions
|
||||
("susi_dachshund", "Susi dachshund dog, brown and black, long body, floppy ears, pink collar, happy"),
|
||||
("dog_husky", "husky dog, fluffy grey white, blue eyes, friendly"),
|
||||
("dog_shepherd", "german shepherd, brown black, alert protective"),
|
||||
("cat_tabby", "orange tabby cat, striped, lazy curious"),
|
||||
("cat_black", "black cat, green eyes, mysterious"),
|
||||
|
||||
# Farm
|
||||
("cow_spotted", "dairy cow, black white spots, friendly"),
|
||||
("sheep_fluffy", "white sheep, very fluffy wool, cute"),
|
||||
("chicken_white", "white chicken, red comb, pecking"),
|
||||
("pig_pink", "pink pig, curly tail, muddy happy"),
|
||||
("goat_brown", "brown goat, small horns, playful"),
|
||||
("horse_brown", "brown horse, black mane, majestic"),
|
||||
("donkey_grey", "grey donkey, big ears, stubborn"),
|
||||
("rabbit_white", "white rabbit, long ears, fluffy"),
|
||||
|
||||
# Wildlife
|
||||
("deer_forest", "forest deer, brown, antlers, graceful"),
|
||||
("wolf_grey", "grey wolf, fierce, pack hunter"),
|
||||
("bear_brown", "brown bear, large, powerful"),
|
||||
("fox_red", "red fox, bushy tail, clever"),
|
||||
("boar_wild", "wild boar, tusks, aggressive"),
|
||||
("owl_barn", "barn owl, white face, wise"),
|
||||
("crow_black", "black crow, intelligent, ominous"),
|
||||
|
||||
# Legendary
|
||||
("phoenix_chicken", "Phoenix Chicken, fire feathers, glowing orange-red, legendary rare"),
|
||||
("unicorn", "white Unicorn, rainbow mane, golden spiral horn, magical"),
|
||||
("golden_goose", "Golden Goose, shimmering gold feathers, lays golden eggs"),
|
||||
("fire_sheep", "Fire Sheep, burning wool flames, magical mutant"),
|
||||
("three_headed_chicken", "Three-Headed Chicken mutant, bizarre, three heads"),
|
||||
]
|
||||
|
||||
for name, desc in animals:
|
||||
assets.append({"cat": "zivali", "file": f"{name}.png", "prompt": f"2D indie game animal sprite, {desc}, full body side view"})
|
||||
# Walk animation
|
||||
for frame in ["walk1", "walk2", "idle"]:
|
||||
assets.append({
|
||||
"cat": "zivali",
|
||||
"file": f"{name}_{frame}.png",
|
||||
"prompt": f"2D indie game animal sprite, {desc}, {frame} animation frame"
|
||||
})
|
||||
|
||||
# ========================================================================
|
||||
# 4. ZOMBIES & MUTANTS (~80)
|
||||
# ========================================================================
|
||||
|
||||
mutants = [
|
||||
("zombie_basic", "basic zombie, shambling, torn clothes, grey skin, undead"),
|
||||
("zombie_runner", "fast zombie, sprinting, aggressive, rage face"),
|
||||
("zombie_bloated", "bloated zombie, huge swollen, toxic green drool"),
|
||||
("zombie_armored", "armored zombie, riot gear, tough, slow"),
|
||||
("zombie_crawler", "crawler zombie, no legs, crawling desperately"),
|
||||
("zombie_screamer", "screamer zombie, wide mouth, alerting scream"),
|
||||
("zombie_dreadlocks", "zombie with dreadlocks, brown shirt, farmer style"),
|
||||
|
||||
("mutant_dog", "mutant dog, hairless, sores, vicious"),
|
||||
("mutant_rat_giant", "giant rat mutant, dog sized, disease"),
|
||||
("mutant_spider", "giant spider, eight legs, web, terrifying"),
|
||||
("mutant_crow", "mutant crow, large, red eyes, circling"),
|
||||
|
||||
("slime_green", "green slime monster, bouncy blob, cute-creepy"),
|
||||
("slime_blue", "blue slime, water element, wobbly"),
|
||||
("slime_red", "red slime, fire element, hot"),
|
||||
("slime_purple", "purple slime, poison element, toxic"),
|
||||
]
|
||||
|
||||
for name, desc in mutants:
|
||||
assets.append({"cat": "mutanti", "file": f"{name}.png", "prompt": f"2D indie game monster sprite, {desc}, full body"})
|
||||
for frame in ["walk1", "walk2", "attack"]:
|
||||
assets.append({
|
||||
"cat": "mutanti",
|
||||
"file": f"{name}_{frame}.png",
|
||||
"prompt": f"2D indie game monster sprite, {desc}, {frame} animation"
|
||||
})
|
||||
|
||||
# ========================================================================
|
||||
# 5. BOSSES (~30)
|
||||
# ========================================================================
|
||||
|
||||
bosses = [
|
||||
("boss_zombie_king", "Zombie King, massive undead ruler, rotting crown, commands zombies"),
|
||||
("boss_slime_emperor", "Slime Emperor, gigantic rainbow slime, crown, bouncing"),
|
||||
("boss_trex", "T-Rex dinosaur, massive prehistoric predator, huge jaws"),
|
||||
("boss_kraken", "Kraken, giant sea monster, many tentacles, ocean terror"),
|
||||
("boss_troll_alpha", "Alpha Troll King, massive green troll, tribal crown, Gronk's enemy"),
|
||||
("boss_dragon_fire", "Fire Dragon, red scales, breathing flames, wings"),
|
||||
("boss_dragon_ice", "Ice Dragon, blue scales, frost breath, majestic"),
|
||||
("boss_spider_queen", "Spider Queen, giant spider, egg sacs, web lair"),
|
||||
("boss_werewolf", "Werewolf Alpha, massive wolf-human hybrid, moonlight"),
|
||||
("boss_vampire", "Vampire Lord, ancient, cape, fangs, pale"),
|
||||
("boss_phoenix", "Phoenix boss, giant fire bird, rebirth"),
|
||||
("boss_hydra", "Hydra, multi-headed serpent, regenerating"),
|
||||
("boss_golem", "Stone Golem, massive rock creature, ancient"),
|
||||
("boss_treant", "Elder Treant, giant living tree, nature guardian"),
|
||||
("boss_demon", "Demon Prince, hellfire, horns, terrifying"),
|
||||
]
|
||||
|
||||
for name, desc in bosses:
|
||||
assets.append({"cat": "bosses", "file": f"{name}.png", "prompt": f"2D indie game boss sprite, {desc}, full body, large 128px"})
|
||||
for frame in ["idle", "attack1", "attack2"]:
|
||||
assets.append({
|
||||
"cat": "bosses",
|
||||
"file": f"{name}_{frame}.png",
|
||||
"prompt": f"2D indie game boss sprite, {desc}, {frame} animation, large"
|
||||
})
|
||||
|
||||
# ========================================================================
|
||||
# 6. ENVIRONMENT - TILES & OBJECTS (~200)
|
||||
# ========================================================================
|
||||
|
||||
# Biome tiles (32x32 seamless)
|
||||
biome_tiles = [
|
||||
("tile_grass_green", "green grass ground tile, 32x32 seamless"),
|
||||
("tile_grass_dry", "dry brown grass tile, 32x32 seamless"),
|
||||
("tile_dirt_brown", "brown dirt path tile, 32x32 seamless"),
|
||||
("tile_sand_yellow", "yellow sand beach tile, 32x32 seamless"),
|
||||
("tile_snow_white", "white snow tile, 32x32 seamless"),
|
||||
("tile_concrete_cracked", "cracked concrete urban tile, 32x32 seamless"),
|
||||
("tile_asphalt_broken", "broken asphalt road tile, 32x32 seamless"),
|
||||
("tile_water_shallow", "shallow blue water tile, 32x32 seamless"),
|
||||
("tile_water_deep", "deep blue water tile, 32x32 seamless"),
|
||||
("tile_swamp_mud", "murky swamp mud tile, 32x32 seamless"),
|
||||
("tile_lava_hot", "hot lava tile glowing, 32x32 seamless"),
|
||||
("tile_ice_blue", "blue ice frozen tile, 32x32 seamless"),
|
||||
("tile_rock_grey", "grey rocky ground tile, 32x32 seamless"),
|
||||
("tile_wood_plank", "wooden floor plank tile, 32x32 seamless"),
|
||||
("tile_stone_brick", "stone brick floor tile, 32x32 seamless"),
|
||||
]
|
||||
|
||||
for name, desc in biome_tiles:
|
||||
assets.append({"cat": "environment", "file": f"{name}.png", "prompt": f"2D game tile, {desc}"})
|
||||
|
||||
# Environment objects
|
||||
env_objects = [
|
||||
("tree_oak", "oak tree, green leaves, brown trunk"),
|
||||
("tree_pine", "pine tree, evergreen, cone shaped"),
|
||||
("tree_dead", "dead tree, no leaves, gnarled"),
|
||||
("tree_cherry", "cherry blossom tree, pink flowers"),
|
||||
("tree_palm", "palm tree, coconuts, tropical"),
|
||||
|
||||
("bush_green", "green bush, leafy"),
|
||||
("bush_berry", "berry bush, red berries"),
|
||||
("flower_red", "red flowers patch"),
|
||||
("flower_blue", "blue flowers patch"),
|
||||
("flower_yellow", "sunflowers, tall yellow"),
|
||||
|
||||
("rock_small", "small rocks pile"),
|
||||
("rock_large", "large boulder, moss"),
|
||||
("log_fallen", "fallen log, decomposing"),
|
||||
("mushroom_brown", "brown mushrooms cluster"),
|
||||
("mushroom_red", "red spotted mushrooms"),
|
||||
|
||||
("fence_wood", "wooden fence section"),
|
||||
("fence_metal", "metal chain fence section"),
|
||||
("gate_wood", "wooden gate"),
|
||||
("bridge_wood", "wooden bridge section"),
|
||||
|
||||
("campfire", "campfire, flames, logs"),
|
||||
("tent_camping", "camping tent, green"),
|
||||
("chest_wooden", "wooden treasure chest"),
|
||||
("barrel_wood", "wooden barrel, storage"),
|
||||
("crate_wooden", "wooden shipping crate"),
|
||||
|
||||
("ruin_wall", "ruined brick wall section"),
|
||||
("ruin_pillar", "broken stone pillar"),
|
||||
("car_rusted", "rusted abandoned car"),
|
||||
("sign_warning", "warning sign post"),
|
||||
]
|
||||
|
||||
for name, desc in env_objects:
|
||||
assets.append({"cat": "environment", "file": f"{name}.png", "prompt": f"2D indie game object sprite, {desc}"})
|
||||
|
||||
# ========================================================================
|
||||
# 7. ITEMS - WEAPONS, TOOLS, EQUIPMENT (~150)
|
||||
# ========================================================================
|
||||
|
||||
items = [
|
||||
# Tools
|
||||
("tool_axe_wood", "wooden axe, chopping tool"),
|
||||
("tool_axe_iron", "iron axe, upgraded"),
|
||||
("tool_pickaxe_wood", "wooden pickaxe, mining"),
|
||||
("tool_pickaxe_iron", "iron pickaxe, upgraded"),
|
||||
("tool_shovel", "shovel, digging"),
|
||||
("tool_hoe", "farming hoe, tilling"),
|
||||
("tool_hammer", "hammer, building"),
|
||||
("tool_saw", "hand saw, cutting"),
|
||||
|
||||
# Weapons
|
||||
("weapon_sword_iron", "iron sword, combat"),
|
||||
("weapon_sword_silver", "silver sword, glowing"),
|
||||
("weapon_dagger", "dagger, quick"),
|
||||
("weapon_spear", "wooden spear, hunting"),
|
||||
("weapon_bow_wood", "wooden bow with arrows"),
|
||||
("weapon_bow_silver", "silver bow, magical"),
|
||||
("weapon_crossbow", "crossbow, powerful"),
|
||||
|
||||
# Magic wands (6 types)
|
||||
("wand_fire", "fire magic wand, red crystal tip, flames"),
|
||||
("wand_ice", "ice magic wand, blue crystal, frost"),
|
||||
("wand_lightning", "lightning wand, yellow crystal, sparks"),
|
||||
("wand_earth", "earth magic wand, green crystal, nature"),
|
||||
("wand_shadow", "shadow magic wand, purple crystal, darkness"),
|
||||
("wand_healing", "healing wand, white crystal, glow"),
|
||||
|
||||
# Special items
|
||||
("ana_bracelet", "Ana's magical bracelet, glowing, family heirloom"),
|
||||
("gronk_vape", "Gronk's golden vape device, colorful, smoking"),
|
||||
|
||||
# Equipment
|
||||
("backpack_small", "small leather backpack"),
|
||||
("backpack_large", "large hiking backpack"),
|
||||
("helmet_metal", "metal protective helmet"),
|
||||
("boots_leather", "leather boots"),
|
||||
("gloves_work", "work gloves"),
|
||||
("gas_mask", "gas mask, protection"),
|
||||
|
||||
# Resources
|
||||
("resource_wood", "wood logs pile"),
|
||||
("resource_stone", "stone rocks pile"),
|
||||
("resource_iron", "iron ore chunks"),
|
||||
("resource_gold", "gold nuggets"),
|
||||
("resource_crystal", "blue crystal gem"),
|
||||
|
||||
# Consumables
|
||||
("food_bread", "bread loaf"),
|
||||
("food_apple", "red apple"),
|
||||
("food_meat", "cooked meat"),
|
||||
("potion_health", "health potion red"),
|
||||
("potion_mana", "mana potion blue"),
|
||||
("water_bottle", "water bottle"),
|
||||
]
|
||||
|
||||
for name, desc in items:
|
||||
assets.append({"cat": "items", "file": f"{name}.png", "prompt": f"2D indie game item icon, {desc}, inventory sprite"})
|
||||
|
||||
# ========================================================================
|
||||
# 8. UI ELEMENTS (~30)
|
||||
# ========================================================================
|
||||
|
||||
ui = [
|
||||
("ui_health_bar", "health bar, red hearts row"),
|
||||
("ui_energy_bar", "energy bar, green lightning"),
|
||||
("ui_inventory_slot", "inventory slot, wooden frame"),
|
||||
("ui_button_menu", "menu button, wooden, round"),
|
||||
("ui_cursor_hand", "hand cursor pointer"),
|
||||
("ui_icon_gold", "gold coin icon"),
|
||||
("ui_icon_attack", "sword attack icon"),
|
||||
("ui_icon_defense", "shield defense icon"),
|
||||
]
|
||||
|
||||
for name, desc in ui:
|
||||
assets.append({"cat": "ui", "file": f"{name}.png", "prompt": f"2D game UI element, {desc}, clean"})
|
||||
|
||||
return assets
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# GOOGLE AI IMAGE GENERATION
|
||||
# ============================================================================
|
||||
|
||||
def setup_google_ai():
|
||||
"""Setup Google AI API"""
|
||||
api_key = os.environ.get("GOOGLE_AI_API_KEY") or os.environ.get("GEMINI_API_KEY")
|
||||
if not api_key:
|
||||
# Try to read from file
|
||||
key_file = Path.home() / ".config" / "google_ai_key.txt"
|
||||
if key_file.exists():
|
||||
api_key = key_file.read_text().strip()
|
||||
|
||||
if api_key:
|
||||
genai.configure(api_key=api_key)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def generate_image_google(prompt: str, output_path: Path) -> bool:
|
||||
"""Generate image using Google AI"""
|
||||
try:
|
||||
full_prompt = STYLE_PREFIX + prompt + STYLE_SUFFIX
|
||||
|
||||
# Use Imagen model
|
||||
model = genai.ImageGenerationModel("imagen-3.0-generate-002")
|
||||
result = model.generate_images(
|
||||
prompt=full_prompt,
|
||||
number_of_images=1,
|
||||
aspect_ratio="1:1",
|
||||
safety_filter_level="block_only_high",
|
||||
person_generation="allow_adult",
|
||||
)
|
||||
|
||||
if result.images:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
result.images[0].save(str(output_path))
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 70)
|
||||
print("🎮 DOLINA SMRTI V7.0 - FINALNI GENERATOR")
|
||||
print(" 2D Indie Cartoon Style | Green Chroma-Key BG")
|
||||
print(" Based on approved Gronk/Kai test images")
|
||||
print("=" * 70)
|
||||
|
||||
if not setup_google_ai():
|
||||
print("❌ Google AI API key not found")
|
||||
print(" Set GOOGLE_AI_API_KEY environment variable")
|
||||
return
|
||||
|
||||
print("✅ Google AI configured")
|
||||
|
||||
print("\n📋 Building Master Registry...")
|
||||
ASSETS = generate_registry()
|
||||
print(f"📊 Total: {len(ASSETS)} assets")
|
||||
|
||||
# Count by category
|
||||
cats = {}
|
||||
for a in ASSETS:
|
||||
cats[a["cat"]] = cats.get(a["cat"], 0) + 1
|
||||
print("\nPo kategorijah:")
|
||||
for cat, count in sorted(cats.items(), key=lambda x: -x[1]):
|
||||
print(f" {cat}: {count}")
|
||||
|
||||
existing = sum(1 for a in ASSETS if (OUTPUT_DIR / a["cat"] / a["file"]).exists())
|
||||
print(f"\n✅ Exist: {existing} | 🎯 Generate: {len(ASSETS) - existing}")
|
||||
|
||||
print("\n🎮 STARTING GENERATION...\n")
|
||||
|
||||
success, skip, fail = 0, 0, 0
|
||||
|
||||
for i, asset in enumerate(ASSETS, 1):
|
||||
path = OUTPUT_DIR / asset["cat"] / asset["file"]
|
||||
|
||||
if path.exists():
|
||||
skip += 1
|
||||
continue
|
||||
|
||||
print(f"[{i}/{len(ASSETS)}] 🎨 {asset['file'][:40]}...")
|
||||
|
||||
if generate_image_google(asset["prompt"], path):
|
||||
print(f" ✅ SAVED")
|
||||
success += 1
|
||||
else:
|
||||
print(f" ❌ FAILED")
|
||||
fail += 1
|
||||
|
||||
if i % 25 == 0:
|
||||
print(f"\n📊 [{i}/{len(ASSETS)}] ✅{success} ⏭️{skip} ❌{fail}\n")
|
||||
|
||||
time.sleep(1) # Rate limiting
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("🎮 GENERATION COMPLETE!")
|
||||
print(f"✅ Success: {success} | ⏭️ Skip: {skip} | ❌ Fail: {fail}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||