156 lines
4.8 KiB
Python
156 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Reorganize assets with proper structure:
|
||
- Each asset gets its own subfolder
|
||
- Original 1024x1024 file: assetname_1024x1024.png
|
||
- Resized file: assetname_32x32.png (or other size)
|
||
"""
|
||
|
||
import os
|
||
import shutil
|
||
from pathlib import Path
|
||
from PIL import Image
|
||
|
||
# Target sizes for each category
|
||
RESIZE_CONFIG = {
|
||
'terrain': 32,
|
||
'crops': 32,
|
||
'buildings': 32,
|
||
'items': 16,
|
||
'ui': None, # Keep original
|
||
'effects': 32,
|
||
'environment': {
|
||
'campfire': 32,
|
||
'dead_tree': (32, 64),
|
||
'rock': 32
|
||
},
|
||
'characters': 32,
|
||
'enemies': 32
|
||
}
|
||
|
||
def get_target_size(category: str, filename: str):
|
||
"""Get target resize dimensions"""
|
||
config = RESIZE_CONFIG.get(category)
|
||
|
||
if config is None:
|
||
return None
|
||
|
||
if isinstance(config, dict):
|
||
for key, size in config.items():
|
||
if key in filename:
|
||
return size
|
||
return 32
|
||
|
||
return config
|
||
|
||
def reorganize_asset(asset_path: Path, category_dir: Path, target_size):
|
||
"""
|
||
Reorganize single asset - creates 3 versions:
|
||
- Original: 1024x1024 (full quality archive)
|
||
- Preview: 256x256 (visible in file explorer)
|
||
- Sprite: 32x32 (game-ready tile)
|
||
"""
|
||
|
||
try:
|
||
# Get asset base name (without extension)
|
||
asset_name = asset_path.stem
|
||
|
||
# Create subfolder
|
||
asset_folder = category_dir / asset_name
|
||
asset_folder.mkdir(exist_ok=True)
|
||
|
||
# Load original
|
||
img = Image.open(asset_path)
|
||
orig_width, orig_height = img.size
|
||
|
||
# Save original with dimensions in name
|
||
original_filename = f"{asset_name}_{orig_width}x{orig_height}.png"
|
||
original_path = asset_folder / original_filename
|
||
img.save(original_path, 'PNG')
|
||
|
||
print(f" 📁 {asset_name}/")
|
||
print(f" ✅ Original: {original_filename} ({orig_width}×{orig_height})")
|
||
|
||
# Create PREVIEW version (256x256 - visible in file explorer!)
|
||
preview_size = 256
|
||
preview = img.resize((preview_size, preview_size), Image.Resampling.LANCZOS)
|
||
preview_filename = f"{asset_name}_preview_{preview_size}x{preview_size}.png"
|
||
preview_path = asset_folder / preview_filename
|
||
preview.save(preview_path, 'PNG', optimize=True)
|
||
print(f" ✅ Preview: {preview_filename} (VISIBLE SIZE)")
|
||
|
||
# Create SPRITE version (32x32 - for game)
|
||
if target_size is not None:
|
||
if isinstance(target_size, tuple):
|
||
sprite = img.resize(target_size, Image.Resampling.LANCZOS)
|
||
new_width, new_height = target_size
|
||
else:
|
||
sprite = img.resize((target_size, target_size), Image.Resampling.LANCZOS)
|
||
new_width, new_height = target_size, target_size
|
||
|
||
sprite_filename = f"{asset_name}_sprite_{new_width}x{new_height}.png"
|
||
sprite_path = asset_folder / sprite_filename
|
||
sprite.save(sprite_path, 'PNG', optimize=True)
|
||
|
||
print(f" ✅ Sprite: {sprite_filename} (GAME SIZE)")
|
||
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f" ❌ Error with {asset_path.name}: {e}")
|
||
return False
|
||
|
||
def process_category(base_dir: Path, category: str):
|
||
"""Process all assets in category"""
|
||
|
||
category_path = base_dir / category
|
||
if not category_path.exists():
|
||
return 0
|
||
|
||
print(f"\n{'='*70}")
|
||
print(f"📂 CATEGORY: {category}/")
|
||
print(f"{'='*70}")
|
||
|
||
# Get all PNG files (not in subfolders)
|
||
png_files = [f for f in category_path.glob('*.png') if f.is_file()]
|
||
|
||
if not png_files:
|
||
print(" No PNG files found in root")
|
||
return 0
|
||
|
||
count = 0
|
||
for png_file in png_files:
|
||
target_size = get_target_size(category, png_file.stem)
|
||
if reorganize_asset(png_file, category_path, target_size):
|
||
# Remove original file after successful reorganization
|
||
png_file.unlink()
|
||
count += 1
|
||
|
||
return count
|
||
|
||
def main():
|
||
print("=" * 70)
|
||
print("🗂️ ASSET REORGANIZATION: SUBFOLDERS WITH ORIGINALS + RESIZED")
|
||
print("=" * 70)
|
||
|
||
demo_dir = Path('assets/images/demo')
|
||
print(f"\n📦 Processing: {demo_dir}")
|
||
|
||
total = 0
|
||
for category in RESIZE_CONFIG.keys():
|
||
if category != 'environment':
|
||
total += process_category(demo_dir, category)
|
||
|
||
total += process_category(demo_dir, 'environment')
|
||
|
||
print("\n" + "=" * 70)
|
||
print(f"✅ COMPLETE! Reorganized {total} assets")
|
||
print("=" * 70)
|
||
print("\n📁 Structure: category/assetname/")
|
||
print(" - assetname_1024x1024.png (ORIGINAL - full quality)")
|
||
print(" - assetname_preview_256x256.png (PREVIEW - visible size)")
|
||
print(" - assetname_sprite_32x32.png (SPRITE - game ready)")
|
||
|
||
if __name__ == "__main__":
|
||
main()
|