Files
novafarma/scripts/batch_cleanup_all_assets.py
David Kotnik 3ca2cd7f86 Complete Faza 1&2 Status + Batch Visual Cleanup
- Created comprehensive FAZA1_GENERATION_STATUS.md with 10 categories tracking 176 tasks
- Auto-sync system for real-time progress updates
- Batch cleanup: 1411 images scanned across references/, assets/, style_test_samples/
- 33 backgrounds removed total (24 previous + 9 new)
- Updated ROADMAP.md: Visual Cleanup  Complete
- Script: batch_cleanup_all_assets.py for automated processing
- Critical path identified: 17 tasks (60-80h) to Kickstarter Demo ready
2026-01-05 12:08:24 +01:00

183 lines
5.6 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
BATCH VISUAL ASSET CLEANUP
Removes backgrounds from ALL image assets in the project.
Processes: /references/, /assets/, /style_test_samples/
Features:
- Multi-folder scanning
- Chroma keying (green #00FF00 removal)
- Smart detection of already transparent images
- Progress tracking
- Automatic _nobg.png generation
"""
import os
from PIL import Image
import numpy as np
from pathlib import Path
# Configuration
SEARCH_FOLDERS = [
'references',
'assets/images',
'assets/bugs',
'assets/tools',
'assets/crops',
'assets/buildings',
'assets/characters',
'assets/enemies',
'assets/npcs',
'style_test_samples'
]
GREEN_KEY = (0, 255, 0) # #00FF00
TOLERANCE = 30 # Color variance tolerance
def has_transparency(image):
"""Check if image already has transparent pixels"""
if image.mode != 'RGBA':
return False
alpha = np.array(image)[:, :, 3]
return np.any(alpha < 255)
def remove_green_background(image_path, output_path):
"""Remove green chroma key background and save as transparent PNG"""
try:
img = Image.open(image_path).convert('RGBA')
data = np.array(img)
# Check if already transparent
if has_transparency(img):
print(f" ⏭️ Already transparent: {os.path.basename(image_path)}")
return False
# Extract RGB channels
red, green, blue, alpha = data[:, :, 0], data[:, :, 1], data[:, :, 2], data[:, :, 3]
# Create mask for green pixels (with tolerance)
mask = (
(np.abs(red.astype(int) - GREEN_KEY[0]) <= TOLERANCE) &
(np.abs(green.astype(int) - GREEN_KEY[1]) <= TOLERANCE) &
(np.abs(blue.astype(int) - GREEN_KEY[2]) <= TOLERANCE)
)
# Check if green background exists
green_pixel_count = np.sum(mask)
if green_pixel_count == 0:
print(f" No green background: {os.path.basename(image_path)}")
return False
# Set alpha to 0 for green pixels
data[:, :, 3] = np.where(mask, 0, 255)
# Save as transparent PNG
result = Image.fromarray(data, 'RGBA')
result.save(output_path, 'PNG')
percentage = (green_pixel_count / (data.shape[0] * data.shape[1])) * 100
print(f" ✅ Processed: {os.path.basename(image_path)} ({percentage:.1f}% background removed)")
return True
except Exception as e:
print(f" ❌ ERROR: {os.path.basename(image_path)} - {e}")
return False
def scan_and_process(base_dir):
"""Scan all configured folders and process images"""
stats = {
'total_found': 0,
'processed': 0,
'skipped_transparent': 0,
'skipped_no_green': 0,
'errors': 0
}
print("🔍 SCANNING FOR IMAGES...\n")
for folder in SEARCH_FOLDERS:
folder_path = os.path.join(base_dir, folder)
if not os.path.exists(folder_path):
print(f"⏭️ Skipping (not found): {folder}")
continue
print(f"\n📁 Processing: {folder}/")
print("=" * 60)
# Find all image files
image_files = []
for ext in ['*.png', '*.jpg', '*.jpeg']:
image_files.extend(Path(folder_path).rglob(ext))
folder_stats = {
'found': len(image_files),
'processed': 0
}
for img_path in sorted(image_files):
# Skip already processed files
if '_nobg' in img_path.stem:
continue
stats['total_found'] += 1
# Generate output filename
output_path = img_path.parent / f"{img_path.stem}_nobg.png"
# Skip if already exists
if output_path.exists():
print(f" ⏭️ Already exists: {output_path.name}")
stats['skipped_transparent'] += 1
continue
# Process the image
result = remove_green_background(str(img_path), str(output_path))
if result:
stats['processed'] += 1
folder_stats['processed'] += 1
elif result is False:
# Check reason from function output
stats['skipped_no_green'] += 1
print(f"\n📊 Folder Summary: {folder_stats['processed']}/{folder_stats['found']} processed")
return stats
def main():
"""Main execution"""
print("=" * 60)
print("🎨 BATCH VISUAL ASSET CLEANUP")
print("=" * 60)
print(f"Target folders: {len(SEARCH_FOLDERS)}")
print(f"Chroma key: RGB{GREEN_KEY} ±{TOLERANCE}")
print("=" * 60)
# Get project root
script_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(script_dir)
# Process all folders
stats = scan_and_process(project_root)
# Final report
print("\n" + "=" * 60)
print("📊 FINAL REPORT")
print("=" * 60)
print(f"Total images found: {stats['total_found']}")
print(f"✅ Successfully processed: {stats['processed']}")
print(f"⏭️ Already transparent: {stats['skipped_transparent']}")
print(f" No green background: {stats['skipped_no_green']}")
print(f"❌ Errors: {stats['errors']}")
print("=" * 60)
if stats['processed'] > 0:
print(f"\n✅ CLEANUP COMPLETE! {stats['processed']} backgrounds removed.")
else:
print("\n✅ All images already clean!")
if __name__ == "__main__":
main()