new images
This commit is contained in:
187
asset-work/generate_all_captions_combo.py
Executable file
187
asset-work/generate_all_captions_combo.py
Executable file
@@ -0,0 +1,187 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate combo images from all kq4-decompile visual images that have captions."""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
DEFAULT_CAPTION_TEXT = "oil painting style"
|
||||
|
||||
|
||||
def find_captions_for_image(image_path: Path) -> list[tuple[Path, str, int]]:
|
||||
"""Find all caption files for a visual image.
|
||||
|
||||
Looks for caption files in asset-work/kq4_XXX_room_name/ directory.
|
||||
Returns list of (caption_path, caption_text, caption_number) tuples.
|
||||
Uses a set to avoid duplicates when multiple room folders match.
|
||||
|
||||
Args:
|
||||
image_path: Path to the visual image
|
||||
|
||||
Returns:
|
||||
List of tuples with (caption_file_path, caption_text, caption_number)
|
||||
"""
|
||||
image_basename = os.path.basename(image_path)
|
||||
room_number = image_basename.replace("pic_", "").split("_")[0]
|
||||
|
||||
room_folder_pattern = f"kq4_{room_number}_*"
|
||||
script_dir = Path(__file__).parent.resolve()
|
||||
|
||||
captions_set = set()
|
||||
captions = []
|
||||
for room_dir in script_dir.glob(room_folder_pattern):
|
||||
if room_dir.is_dir():
|
||||
for caption_file in sorted(room_dir.glob("caption_*.txt")):
|
||||
match = re.match(r"caption_(\d+)\.txt", caption_file.name)
|
||||
if match:
|
||||
caption_num = int(match.group(1))
|
||||
caption_key = (caption_num, caption_file.name)
|
||||
if caption_key not in captions_set:
|
||||
captions_set.add(caption_key)
|
||||
with open(caption_file, "r") as f:
|
||||
caption_text = f.read().strip()
|
||||
captions.append((caption_file, caption_text, caption_num))
|
||||
|
||||
return sorted(captions, key=lambda x: x[2]) if captions else [(None, DEFAULT_CAPTION_TEXT, 0)]
|
||||
|
||||
|
||||
def find_caption_for_image(image_path: Path) -> tuple[Path | None, str]:
|
||||
"""Find first caption file for a visual image.
|
||||
|
||||
Args:
|
||||
image_path: Path to the visual image
|
||||
|
||||
Returns:
|
||||
Tuple of (caption_file_path or None, caption_text or default)
|
||||
"""
|
||||
captions = find_captions_for_image(image_path)
|
||||
if captions and captions[0][0]:
|
||||
return captions[0][0], captions[0][1]
|
||||
return None, DEFAULT_CAPTION_TEXT
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate combo images from all kq4-decompile visual images with captions"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Dry run mode - validate without generating",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
script_dir = Path(__file__).parent.resolve()
|
||||
generator = script_dir / "generate_multiple_combo.py"
|
||||
|
||||
dry_run = args.dry_run
|
||||
|
||||
if not generator.exists():
|
||||
print(f"Error: generate_multiple_combo.py not found in {script_dir}")
|
||||
sys.exit(1)
|
||||
|
||||
print("Finding all kq4-decompile visual images...")
|
||||
visual_images = list(Path("kq4-sierra-decompile/rooms").rglob("pic_*_visual.png"))
|
||||
|
||||
total = len(visual_images)
|
||||
|
||||
if total == 0:
|
||||
print("No kq4-decompile visual images found!")
|
||||
sys.exit(0)
|
||||
|
||||
print(f"Found {total} visual image(s)")
|
||||
|
||||
all_images_to_process = []
|
||||
for image_path in visual_images:
|
||||
captions = find_captions_for_image(image_path)
|
||||
for caption_path, caption_text, caption_num in captions:
|
||||
all_images_to_process.append((image_path, caption_text, caption_path, caption_num))
|
||||
|
||||
total_captions = len(all_images_to_process)
|
||||
print(f"Found {total_captions} captions to process ({len(visual_images)} rooms)")
|
||||
|
||||
if dry_run:
|
||||
print("\nDRY RUN MODE - Validating all visual images")
|
||||
|
||||
counter = 0
|
||||
failed = 0
|
||||
total_existing = 0
|
||||
total_created = 0
|
||||
total_needed = 0
|
||||
|
||||
variations_per_image = 1
|
||||
|
||||
for image_path, caption_text, caption_path, caption_num in all_images_to_process:
|
||||
counter += 1
|
||||
|
||||
caption_info = f"[caption_{caption_num}]" if caption_path else "[default]"
|
||||
|
||||
cmd = [
|
||||
"python3",
|
||||
str(generator),
|
||||
str(image_path),
|
||||
caption_text,
|
||||
"--count",
|
||||
str(variations_per_image),
|
||||
"--caption-num",
|
||||
str(caption_num),
|
||||
]
|
||||
if dry_run:
|
||||
cmd.append("--dry-run")
|
||||
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
print(result.stdout)
|
||||
|
||||
existing_match = re.search(
|
||||
r"[Ff]ound (\d+) existing variations?", result.stdout
|
||||
)
|
||||
created_match = re.search(r"Created (\d+) new image", result.stdout)
|
||||
|
||||
if existing_match:
|
||||
existing = int(existing_match.group(1))
|
||||
total_existing += existing
|
||||
needed = max(0, variations_per_image - existing)
|
||||
total_needed += needed
|
||||
if created_match:
|
||||
total_created += int(created_match.group(1))
|
||||
|
||||
status = "✓" if result.returncode == 0 else "✗"
|
||||
print(f"[{counter}/{total_captions}] {status} {image_path.name} {caption_info}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
failed += 1
|
||||
print(f"[{counter}/{total_captions}] ✗ {image_path.name} {caption_info} - FAILED")
|
||||
|
||||
print()
|
||||
print("=" * 50)
|
||||
|
||||
if dry_run:
|
||||
print("DRY RUN COMPLETE")
|
||||
print("=" * 50)
|
||||
print(f"Rooms found: {total}")
|
||||
print(f"Captions to process: {total_captions}")
|
||||
print(f"Images already existing: {total_existing}")
|
||||
print(f"Images would be created: {total_needed}")
|
||||
print(f"Total when complete: {total_existing + total_needed}")
|
||||
if failed == 0:
|
||||
print(f"✓ All captions validated successfully!")
|
||||
else:
|
||||
print(f"✗ {failed} of {total_captions} captions failed validation")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("GENERATION COMPLETE")
|
||||
print("=" * 50)
|
||||
print(f"Rooms processed: {total}")
|
||||
print(f"Captions processed: {total_captions}")
|
||||
print(f"Images already existing: {total_existing}")
|
||||
print(f"Images newly created: {total_created}")
|
||||
print(f"Total images now: {total_existing + total_created}")
|
||||
if failed > 0:
|
||||
print(f"Failed: {failed}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user