ASSETS UPDATE: Added references folder with 132 PNGs (resized/sharpened) + Created DEMO_FAZA1 folder structure
This commit is contained in:
41
scripts/utils/convert_desktop_jpg_to_png.py
Normal file
41
scripts/utils/convert_desktop_jpg_to_png.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
TARGET_DIR = "/Users/davidkotnik/Desktop/referencne slike 2"
|
||||
|
||||
def convert_images():
|
||||
if not os.path.exists(TARGET_DIR):
|
||||
print(f"Error: Directory {TARGET_DIR} does not exist.")
|
||||
return
|
||||
|
||||
files = [f for f in os.listdir(TARGET_DIR) if f.lower().endswith(('.jpg', '.jpeg'))]
|
||||
|
||||
if not files:
|
||||
print("No JPG images found to convert.")
|
||||
return
|
||||
|
||||
print(f"Found {len(files)} JPG images. Starting conversion...")
|
||||
|
||||
for filename in files:
|
||||
filepath = os.path.join(TARGET_DIR, filename)
|
||||
name_without_ext = os.path.splitext(filename)[0]
|
||||
new_filename = name_without_ext + ".png"
|
||||
new_filepath = os.path.join(TARGET_DIR, new_filename)
|
||||
|
||||
# Skip if png already exists to save time?
|
||||
# User said "first convert", implyng they might not exist.
|
||||
# But let's overwrite to be sure we have fresh versions if needed.
|
||||
|
||||
try:
|
||||
# Using macOS built-in sips tool
|
||||
subprocess.run(
|
||||
["sips", "-s", "format", "png", filepath, "--out", new_filepath],
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL # Silence standard output for cleaner logs
|
||||
)
|
||||
print(f"✅ Converted: {filename} -> {new_filename}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"❌ Failed to convert {filename}: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
convert_images()
|
||||
122
scripts/utils/intelligent_resize.py
Normal file
122
scripts/utils/intelligent_resize.py
Normal file
@@ -0,0 +1,122 @@
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
SOURCE_DIR = "/Users/davidkotnik/Desktop/referencne slike 2"
|
||||
|
||||
# --- CONFIGURATION: LOGIC FOR RESIZING ---
|
||||
# We define max dimension (width or height, whichever is larger).
|
||||
# The aspect ratio is always preserved.
|
||||
|
||||
RESIZE_RULES = [
|
||||
# --- MASSIVE (512px - 600px) ---
|
||||
# Buildings, large trees, Gronk (Giant Troll)
|
||||
{
|
||||
"keywords": ["zgradba", "hisa", "skedenj", "drevo_veliko", "gronk", "troll", "structure", "objekt", "rudnik", "vhod"],
|
||||
"size": 512
|
||||
},
|
||||
|
||||
# --- MEDIUM-LARGE (350px - 400px) ---
|
||||
# Regular trees, large animals, vehicles
|
||||
{
|
||||
"keywords": ["drevo", "krava", "konj", "medved", "auto", "traktor", "agregat", "sod", "kontejner", "vodnjak", "koca", "sotor"],
|
||||
"size": 384
|
||||
},
|
||||
|
||||
# --- MEDIUM (Standard Character Size: 256px) ---
|
||||
# Humans, zombies, standard props, furniture
|
||||
{
|
||||
"keywords": ["zombi", "kai", "ana", "ata", "mama", "love", "character", "kip", "postelja", "vreca", "miza", "stol", "klop", "kamen_srednji", "ograja"],
|
||||
"size": 256
|
||||
},
|
||||
|
||||
# --- SMALL-MEDIUM (128px - 192px) ---
|
||||
# Small animals, dogs, inventory items held in hand
|
||||
{
|
||||
"keywords": ["pes", "susi", "macka", "kokos", "zajec", "svinja", "ovca", "orodje", "kramp", "sekira", "motika", "lopata", "meč", "puska", "kamen", "grm", "trava"],
|
||||
"size": 192
|
||||
},
|
||||
|
||||
# --- SMALL (64px - 96px) ---
|
||||
# Insects, small items, icons, UI elements
|
||||
{
|
||||
"keywords": ["insekt", "mravlja", "cebela", "metulj", "hrosc", "muha", "komar", "polz", "dezevnik", "ikona", "item", "seme", "steklenica", "hrana", "ui", "gumb"],
|
||||
"size": 96
|
||||
}
|
||||
]
|
||||
|
||||
DEFAULT_SIZE = 256 # Fallback size if no keyword matches
|
||||
|
||||
def install_dependencies():
|
||||
pass # Pillow should be installed from previous step
|
||||
|
||||
def get_target_size(filename):
|
||||
"""Determine size based on filename keywords."""
|
||||
fname = filename.lower()
|
||||
|
||||
for rule in RESIZE_RULES:
|
||||
for keyword in rule["keywords"]:
|
||||
if keyword in fname:
|
||||
# Special case logic could go here (e.g. "zombi_otrok" smaller than "zombi")
|
||||
if "otrok" in fname and rule["size"] > 128:
|
||||
return int(rule["size"] * 0.7) # Kids are 70% size
|
||||
return rule["size"]
|
||||
|
||||
return DEFAULT_SIZE
|
||||
|
||||
def intelligent_resize():
|
||||
if not os.path.exists(SOURCE_DIR):
|
||||
print(f"Directory not found: {SOURCE_DIR}")
|
||||
return
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
print("PIL/Pillow not found. Please pip install Pillow.")
|
||||
return
|
||||
|
||||
files = [f for f in os.listdir(SOURCE_DIR) if f.lower().endswith('.png')]
|
||||
if not files:
|
||||
print("No PNG files found.")
|
||||
return
|
||||
|
||||
print(f"Found {len(files)} PNGs. Starting intelligent resizing...")
|
||||
|
||||
for filename in files:
|
||||
filepath = os.path.join(SOURCE_DIR, filename)
|
||||
|
||||
try:
|
||||
target_size = get_target_size(filename)
|
||||
|
||||
with Image.open(filepath) as img:
|
||||
# Calculate new size preserving aspect ratio
|
||||
width, height = img.size
|
||||
aspect_ratio = width / height
|
||||
|
||||
if width > height:
|
||||
new_width = target_size
|
||||
new_height = int(target_size / aspect_ratio)
|
||||
else:
|
||||
new_height = target_size
|
||||
new_width = int(target_size * aspect_ratio)
|
||||
|
||||
# High quality resampling
|
||||
resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
|
||||
|
||||
# Apply Sharpening (Unsharp Mask) to keep details (piercings!) crisp
|
||||
# Radius 2, Percent 150 is a good standard for "Concept Art" sharpness
|
||||
try:
|
||||
from PIL import ImageFilter
|
||||
resized_img = resized_img.filter(ImageFilter.UnsharpMask(radius=1.5, percent=130, threshold=3))
|
||||
except ImportError:
|
||||
pass # Should be in PIL
|
||||
|
||||
# Save
|
||||
resized_img.save(filepath)
|
||||
print(f"✅ Resized {filename}: {width}x{height} -> {new_width}x{new_height} (Target: {target_size}px)")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error resizing {filename}: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
intelligent_resize()
|
||||
63
scripts/utils/organize_final_assets.py
Normal file
63
scripts/utils/organize_final_assets.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
# Source of Truth
|
||||
SOURCE_DIR = "/Users/davidkotnik/repos/novafarma/assets/references"
|
||||
BASE_ASSETS_DIR = "/Users/davidkotnik/repos/novafarma/assets"
|
||||
|
||||
# Define Categories
|
||||
CATEGORIES = {
|
||||
"zombies": ["zombi", "zombie", "undead"],
|
||||
"characters": ["kai", "ana", "ata", "mama", "gronk", "dr_krnic", "character", "npc"],
|
||||
"animals": ["krava", "svinja", "ovca", "kokos", "pes", "susi", "macka", "netopir", "sova", "volk", "medved", "zival", "insekt", "metulj", "mravlja", "cebela", "polz", "dezevnik", "hrosc", "komar", "muha"],
|
||||
"ui": ["ui_", "gumb", "ikona", "okno", "bar", "status", "dnevnik", "inventar", "kazalec"],
|
||||
"items": ["orodje", "kramp", "lopata", "sekira", "motika", "kosa", "mec", "puska", "stikalo", "sod", "bencin", "kanister", "seme", "rastlina", "pridelki", "marihuana", "konoplja", "hrana", "steklenica", "nacrt", "zvitki"],
|
||||
"environment": ["drevo", "trava", "kamen", "grm", "tile", "tla", "pot", "rudnik", "vhod", "megla", "ozadje", "voda", "resource", "zgradba", "hisa", "koca", "sotor", "skedenj", "objekt", "vodnjak", "ograja", "kip", "postelja", "vreca", "miza", "stol", "klop"]
|
||||
}
|
||||
|
||||
def organize_assets():
|
||||
# 1. Create Directories
|
||||
for category in CATEGORIES:
|
||||
path = os.path.join(BASE_ASSETS_DIR, category)
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
print(f"Created directory: {category}")
|
||||
|
||||
# 2. Sort Files
|
||||
files = [f for f in os.listdir(SOURCE_DIR) if f.lower().endswith('.png')]
|
||||
|
||||
print(f"Sorting {len(files)} files from references...")
|
||||
|
||||
count = 0
|
||||
for filename in files:
|
||||
src_path = os.path.join(SOURCE_DIR, filename)
|
||||
fname_lower = filename.lower()
|
||||
|
||||
assigned = False
|
||||
|
||||
# Check categories in specific order (Zombies first as requested!)
|
||||
# Use lists to prioritize: Zombies > Characters > Animals > UI > Items > Environment
|
||||
priority_order = ["zombies", "characters", "animals", "ui", "items", "environment"]
|
||||
|
||||
for category in priority_order:
|
||||
keywords = CATEGORIES[category]
|
||||
if any(k in fname_lower for k in keywords):
|
||||
dst_path = os.path.join(BASE_ASSETS_DIR, category, filename)
|
||||
shutil.copy2(src_path, dst_path) # COPY, don't move (keep references safe)
|
||||
# print(f"-> {category}: {filename}")
|
||||
assigned = True
|
||||
count += 1
|
||||
break
|
||||
|
||||
if not assigned:
|
||||
# Fallback to 'environment' or 'misc' if unsure?
|
||||
# Let's put in 'environment' as catch-all or create 'misc'
|
||||
dst_path = os.path.join(BASE_ASSETS_DIR, "environment", filename)
|
||||
shutil.copy2(src_path, dst_path)
|
||||
print(f"-> environment (fallback): {filename}")
|
||||
count += 1
|
||||
|
||||
print(f"✅ Successfully organized {count} assets into game folders!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
organize_assets()
|
||||
89
scripts/utils/remove_backgrounds.py
Normal file
89
scripts/utils/remove_backgrounds.py
Normal file
@@ -0,0 +1,89 @@
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
# Define the source directory on the Desktop
|
||||
SOURCE_DIR = "/Users/davidkotnik/Desktop/referencne slike 2"
|
||||
|
||||
def install_dependencies():
|
||||
"""Attempt to install required packages if they are missing."""
|
||||
packages = ["rembg", "Pillow", "onnxruntime"]
|
||||
for package in packages:
|
||||
try:
|
||||
__import__(package)
|
||||
except ImportError:
|
||||
if package == "Pillow":
|
||||
# Pillow is imported as PIL
|
||||
try:
|
||||
__import__("PIL")
|
||||
continue
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
print(f"Installing {package}...")
|
||||
try:
|
||||
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Failed to install {package}: {e}")
|
||||
print("Please try installing it manually: pip install rembg Pillow onnxruntime")
|
||||
sys.exit(1)
|
||||
|
||||
def process_images():
|
||||
# Verify directory
|
||||
if not os.path.exists(SOURCE_DIR):
|
||||
print(f"Error: Directory {SOURCE_DIR} not found.")
|
||||
return
|
||||
|
||||
# Import libraries AFTER installation
|
||||
try:
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
print("Error: Library import failed even after installation attempt.")
|
||||
return
|
||||
|
||||
# Get PNG files
|
||||
files = [f for f in os.listdir(SOURCE_DIR) if f.lower().endswith('.png')]
|
||||
total = len(files)
|
||||
|
||||
if total == 0:
|
||||
print("No PNG files found to process.")
|
||||
return
|
||||
|
||||
print(f"Found {total} PNG images. Starting AI background removal...")
|
||||
print("WARNING: This makes permanent changes to the PNG files (JPG backups are safe).")
|
||||
print("This might take a while depending on your computer speed.")
|
||||
|
||||
success = 0
|
||||
errors = 0
|
||||
|
||||
for i, filename in enumerate(files):
|
||||
file_path = os.path.join(SOURCE_DIR, filename)
|
||||
|
||||
try:
|
||||
print(f"[{i+1}/{total}] Processing: {filename}")
|
||||
|
||||
# Open the image
|
||||
with open(file_path, "rb") as input_file:
|
||||
input_data = input_file.read()
|
||||
|
||||
# Remove background
|
||||
output_data = remove(input_data)
|
||||
|
||||
# Save the result back to the same file (overwrite)
|
||||
with open(file_path, "wb") as output_file:
|
||||
output_file.write(output_data)
|
||||
|
||||
success += 1
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error processing {filename}: {e}")
|
||||
errors += 1
|
||||
|
||||
print(f"\n--- DONE ---")
|
||||
print(f"Successful: {success}")
|
||||
print(f"Errors: {errors}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
install_dependencies()
|
||||
process_images()
|
||||
Reference in New Issue
Block a user