Green Background Removal + TSX Generation + Bug Fixes
Removed green backgrounds from 30 tileset PNGs (16.4M pixels!) Created mass TSX generation script for 3877 individual objects Fixed TiledTestScene cursor crash bug Added micro_farm_8x8 JSON loading support Documentation: GREEN_BACKGROUND_FIX.md, MASS_TSX_GENERATION.md Scripts: - scripts/remove_green_background.py (batch transparency fix) - scripts/generate_mass_tsx.py (3877 .tsx files generator) Backups: assets/tilesets/backup_green_bg/
This commit is contained in:
154
scripts/generate_mass_tsx.py
Normal file
154
scripts/generate_mass_tsx.py
Normal file
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
NovaFarma - Mass TSX Generator
|
||||
================================
|
||||
|
||||
Generates individual .tsx tileset files for all 3877 separated object images.
|
||||
This enables each object to be used independently in Tiled Map Editor.
|
||||
|
||||
Author: Antigravity AI
|
||||
Date: 2025-12-22
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
|
||||
# Configuration
|
||||
ASSETS_DIR = r"c:\novafarma\assets"
|
||||
SOURCE_DIRS = [
|
||||
"narezano_loceno/topdown_objects",
|
||||
"narezano_loceno/krvava_zetev_sprites",
|
||||
"narezano_loceno/tiled_sprites"
|
||||
]
|
||||
OUTPUT_DIR = r"c:\novafarma\assets\tilesets\individual_objects"
|
||||
|
||||
# TSX template
|
||||
TSX_TEMPLATE = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.10" tiledversion="1.11.0" name="{name}" tilewidth="{width}" tileheight="{height}" tilecount="1" columns="1">
|
||||
<image source="{relative_path}" width="{width}" height="{height}"/>
|
||||
</tileset>
|
||||
'''
|
||||
|
||||
def get_image_dimensions(image_path):
|
||||
"""Get width and height of an image."""
|
||||
with Image.open(image_path) as img:
|
||||
return img.size
|
||||
|
||||
def create_tsx_file(png_path, output_dir):
|
||||
"""
|
||||
Create a .tsx file for a given PNG image.
|
||||
|
||||
Args:
|
||||
png_path: Path to PNG file
|
||||
output_dir: Directory to save .tsx file
|
||||
"""
|
||||
# Get image info
|
||||
width, height = get_image_dimensions(png_path)
|
||||
|
||||
# Create name from filename (without extension)
|
||||
filename = os.path.basename(png_path)
|
||||
name = os.path.splitext(filename)[0]
|
||||
|
||||
# Calculate relative path from tilesets/individual_objects/ to the PNG
|
||||
# tilesets/individual_objects/ -> ../../narezano_loceno/[subfolder]/[file].png
|
||||
png_relative = os.path.relpath(png_path, output_dir).replace('\\', '/')
|
||||
|
||||
# Generate TSX content
|
||||
tsx_content = TSX_TEMPLATE.format(
|
||||
name=name,
|
||||
width=width,
|
||||
height=height,
|
||||
relative_path=png_relative
|
||||
)
|
||||
|
||||
# Create .tsx filename
|
||||
tsx_filename = f"{name}.tsx"
|
||||
tsx_path = os.path.join(output_dir, tsx_filename)
|
||||
|
||||
# Write TSX file using UTF-8 BOM encoding for XML stability
|
||||
with open(tsx_path, 'w', encoding='utf-8-sig') as f:
|
||||
f.write(tsx_content)
|
||||
|
||||
return tsx_path
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main function to generate .tsx files for all separated objects.
|
||||
"""
|
||||
print("=" * 70)
|
||||
print("NovaFarma - Mass TSX Generator")
|
||||
print("=" * 70)
|
||||
print()
|
||||
|
||||
# Create output directory
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
print(f"[OK] Output directory: {OUTPUT_DIR}")
|
||||
print()
|
||||
|
||||
# Process each source directory
|
||||
total_created = 0
|
||||
|
||||
for source_dir in SOURCE_DIRS:
|
||||
full_source_path = os.path.join(ASSETS_DIR, source_dir)
|
||||
|
||||
if not os.path.exists(full_source_path):
|
||||
print(f"[WARN] Directory not found: {source_dir}")
|
||||
continue
|
||||
|
||||
# Find all PNG files
|
||||
png_files = list(Path(full_source_path).glob("*.png"))
|
||||
|
||||
if len(png_files) == 0:
|
||||
print(f"[WARN] No PNG files in: {source_dir}")
|
||||
continue
|
||||
|
||||
print(f"[INFO] Processing: {source_dir}")
|
||||
print(f" Found {len(png_files)} PNG files")
|
||||
|
||||
# Create TSX for each PNG
|
||||
created_count = 0
|
||||
error_count = 0
|
||||
for png_file in png_files:
|
||||
try:
|
||||
tsx_path = create_tsx_file(str(png_file), OUTPUT_DIR)
|
||||
created_count += 1
|
||||
|
||||
# Show progress every 100 files
|
||||
if created_count % 100 == 0:
|
||||
print(f" ... {created_count}/{len(png_files)} processed")
|
||||
|
||||
except Exception as e:
|
||||
error_count += 1
|
||||
if error_count <= 5: # Show first 5 errors only
|
||||
print(f"[ERROR] processing {png_file.name}: {e}")
|
||||
|
||||
print(f"[OK] Created {created_count} .tsx files")
|
||||
if error_count > 0:
|
||||
print(f"[WARN] Failed to process {error_count} files")
|
||||
print()
|
||||
total_created += created_count
|
||||
|
||||
# Summary
|
||||
print("=" * 70)
|
||||
print("SUMMARY")
|
||||
print("=" * 70)
|
||||
print(f"[OK] Total .tsx files created: {total_created}")
|
||||
print(f"[OK] Output location: {OUTPUT_DIR}")
|
||||
print()
|
||||
print(">>> All individual objects now ready for Tiled Map Editor!")
|
||||
print("=" * 70)
|
||||
print()
|
||||
print("===============================================================")
|
||||
print("NEXT STEPS:")
|
||||
print("===============================================================")
|
||||
print("1. Open Tiled Map Editor")
|
||||
print("2. Open your map (e.g., micro_farm_128x128.tmx)")
|
||||
print("3. Map -> Add External Tileset...")
|
||||
print("4. Browse to: assets/tilesets/individual_objects/")
|
||||
print("5. Select the .tsx files you want to use")
|
||||
print("6. Start placing objects on your map!")
|
||||
print()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
120
scripts/remove_green_background.py
Normal file
120
scripts/remove_green_background.py
Normal file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
NovaFarma - Batch Remove Green Background
|
||||
==========================================
|
||||
|
||||
This script removes bright green (#00FF00) backgrounds from all PNG images
|
||||
in the assets/tilesets/ directory and replaces them with transparency.
|
||||
|
||||
Author: Antigravity AI
|
||||
Date: 2025-12-22
|
||||
"""
|
||||
|
||||
import os
|
||||
from PIL import Image
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
# Configuration
|
||||
TILESETS_DIR = r"c:\novafarma\assets\tilesets"
|
||||
BACKUP_DIR = r"c:\novafarma\assets\tilesets\backup_green_bg"
|
||||
GREEN_TOLERANCE = 30 # RGB tolerance for green detection
|
||||
|
||||
def is_green_pixel(r, g, b, tolerance=GREEN_TOLERANCE):
|
||||
"""
|
||||
Check if a pixel is bright green (#00FF00 or similar).
|
||||
Returns True if the pixel is greenish.
|
||||
"""
|
||||
# Bright green: high G, low R and B
|
||||
return (g > 200 and r < tolerance and b < tolerance)
|
||||
|
||||
def remove_green_background(image_path, output_path):
|
||||
"""
|
||||
Remove bright green background from an image and make it transparent.
|
||||
"""
|
||||
print(f"Processing: {os.path.basename(image_path)}")
|
||||
|
||||
# Open image
|
||||
img = Image.open(image_path)
|
||||
|
||||
# Convert to RGBA if not already
|
||||
if img.mode != 'RGBA':
|
||||
img = img.convert('RGBA')
|
||||
|
||||
# Get pixel data
|
||||
pixels = img.load()
|
||||
width, height = img.size
|
||||
|
||||
# Process each pixel
|
||||
changed_pixels = 0
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
r, g, b, a = pixels[x, y]
|
||||
|
||||
# If pixel is green, make it transparent
|
||||
if is_green_pixel(r, g, b):
|
||||
pixels[x, y] = (r, g, b, 0) # Set alpha to 0
|
||||
changed_pixels += 1
|
||||
|
||||
# Save the result
|
||||
img.save(output_path, 'PNG')
|
||||
|
||||
print(f" ✅ Done! Changed {changed_pixels:,} pixels to transparent")
|
||||
return changed_pixels
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main function to process all PNG files in tilesets directory.
|
||||
"""
|
||||
print("=" * 60)
|
||||
print("NovaFarma - Batch Green Background Removal")
|
||||
print("=" * 60)
|
||||
print()
|
||||
|
||||
# Create backup directory
|
||||
os.makedirs(BACKUP_DIR, exist_ok=True)
|
||||
print(f"✅ Backup directory: {BACKUP_DIR}")
|
||||
print()
|
||||
|
||||
# Find all PNG files
|
||||
png_files = list(Path(TILESETS_DIR).glob("*.png"))
|
||||
print(f"Found {len(png_files)} PNG files to process\n")
|
||||
|
||||
if len(png_files) == 0:
|
||||
print("❌ No PNG files found!")
|
||||
return
|
||||
|
||||
# Process each file
|
||||
total_changed = 0
|
||||
processed_count = 0
|
||||
|
||||
for png_file in png_files:
|
||||
input_path = str(png_file)
|
||||
filename = png_file.name
|
||||
backup_path = os.path.join(BACKUP_DIR, filename)
|
||||
|
||||
# Create backup
|
||||
shutil.copy2(input_path, backup_path)
|
||||
|
||||
# Remove green background
|
||||
try:
|
||||
changed = remove_green_background(input_path, input_path)
|
||||
total_changed += changed
|
||||
processed_count += 1
|
||||
except Exception as e:
|
||||
print(f" ❌ ERROR: {e}")
|
||||
|
||||
# Summary
|
||||
print()
|
||||
print("=" * 60)
|
||||
print("SUMMARY")
|
||||
print("=" * 60)
|
||||
print(f"✅ Processed: {processed_count}/{len(png_files)} files")
|
||||
print(f"✅ Total pixels changed: {total_changed:,}")
|
||||
print(f"✅ Backups saved to: {BACKUP_DIR}")
|
||||
print()
|
||||
print("Done! All green backgrounds removed! 🎉")
|
||||
print("=" * 60)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user