Files
novafarma/tools/obdelaj_tilesete.py
NovaFarma Dev 7eb1a5874a Avtomatska obdelava tileset slik - 3877 ločenih objektov in TSX datotek
- Ustvarjen skript za ločevanje objektov iz tileset slik (obdelaj_tilesete.py)
- Odstranjevanje zelenega ozadja (#00FF00) iz vseh slik
- Ločevanje posameznih objektov iz multi-object slik
- Pomanjševanje na 50% originalne velikosti
- Obdelanih 234 slik  3877 ločenih objektov

- Ustvarjen skript za generiranje TSX datotek (generiraj_tsx_datoteke.py)
- Avtomatsko generiranje 3877 TSX datotek za Tiled Map Editor
- Pravilna XML struktura za vsak tileset
- Avtomatska detekcija velikosti objektov
- Relativne poti do slik

Rezultati:
- assets/narezano_loceno/ - 3877 ločenih PNG objektov
- assets/tilesets_auto/ - 3877 TSX datotek za Tiled
- Dokumentacija in navodila za uporabo

Vse pripravljeno za uporabo v Tiled Map Editor!
2025-12-21 15:36:42 +01:00

194 lines
6.6 KiB
Python

import os
from PIL import Image
import numpy as np
# ===== NASTAVITVE =====
vhodne_mape = [
r"c:\novafarma\assets\topdown_objects",
r"c:\novafarma\assets\krvava_zetev_sprites",
r"c:\novafarma\assets\tiled_sprites"
]
izhodna_mapa = r"c:\novafarma\assets\narezano_loceno"
nova_velikost_faktor = 0.5 # Pomanjša na 50% (lahko spremeniš)
min_velikost_objekta = 20 # Minimalna velikost objekta v pikslih (ignorira majhne artefakte)
# Barve za odstranjevanje (zeleno ozadje)
ZELENA_BARVA_RGB = [0, 255, 0] # Svetlo zelena (#00FF00)
BARVA_TOLERANCA = 30 # Toleranca za odstranjevanje zelene
# Ustvari izhodno mapo
if not os.path.exists(izhodna_mapa):
os.makedirs(izhodna_mapa)
def odstrani_zeleno_ozadje(img):
"""
Odstrani zeleno ozadje in naredi prosojno.
"""
img_array = np.array(img)
# Če slika nima alpha kanala, dodaj ga
if len(img_array.shape) == 2 or img_array.shape[2] == 3:
# Ustvari alpha kanal
if len(img_array.shape) == 2:
# Grayscale
rgb = np.stack([img_array, img_array, img_array], axis=2)
else:
rgb = img_array[:, :, :3]
alpha = np.ones((img_array.shape[0], img_array.shape[1]), dtype=np.uint8) * 255
img_array = np.concatenate([rgb, alpha[:, :, np.newaxis]], axis=2)
# Najdi zelene piksle
r, g, b = img_array[:, :, 0], img_array[:, :, 1], img_array[:, :, 2]
# Maska za zeleno barvo (kjer je zelena dominantna)
je_zelena = (
(g > r + BARVA_TOLERANCA) & # Zelena je večja od rdeče
(g > b + BARVA_TOLERANCA) & # Zelena je večja od modre
(g > 200) # Zelena je dovolj svetla
)
# Nastavi alpha na 0 za zelene piksle
img_array[:, :, 3][je_zelena] = 0
return Image.fromarray(img_array, 'RGBA')
def najdi_objekte(img):
"""
Najde vse ločene objekte na sliki glede na prosojnost.
Vrne seznam bounding box-ov (x, y, width, height).
"""
from scipy import ndimage
# Pretvori v numpy array
img_array = np.array(img)
# Ustvari masko prosojnosti (kjer alpha > 50)
alpha_channel = img_array[:, :, 3]
maska = alpha_channel > 50
# Najdi povezane komponente (objekte)
labeled, num_features = ndimage.label(maska)
objekti = []
for i in range(1, num_features + 1):
# Najdi koordinate tega objekta
pozicije = np.where(labeled == i)
if len(pozicije[0]) == 0:
continue
y_min, y_max = pozicije[0].min(), pozicije[0].max()
x_min, x_max = pozicije[1].min(), pozicije[1].max()
width = x_max - x_min + 1
height = y_max - y_min + 1
# Ignoriraj premajhne objekte (artefakti)
if width >= min_velikost_objekta and height >= min_velikost_objekta:
objekti.append((x_min, y_min, width, height))
return objekti
def procesiraj_sliko(pot_slike, ime_slike, mapa_izvora):
"""
Procesiraj eno sliko - odstrani zeleno ozadje, najdi vse objekte in jih shrani LOČENO.
"""
try:
img = Image.open(pot_slike).convert("RGBA")
print(f"\n📸 Obdelujem: {ime_slike}")
# 1. ODSTRANI ZELENO OZADJE
img_brez_zelene = odstrani_zeleno_ozadje(img)
print(f" 🟢 Odstranil zeleno ozadje")
# 2. NAJDI VSE OBJEKTE
objekti = najdi_objekte(img_brez_zelene)
if len(objekti) == 0:
print(f" ⚠️ Nisem našel objektov")
return
print(f" ✅ Našel {len(objekti)} objekt(ov)")
# 3. SHRANI VSAK OBJEKT LOČENO
for idx, (x, y, w, h) in enumerate(objekti):
# Izreži objekt
objekt = img_brez_zelene.crop((x, y, x + w, y + h))
# Pomanjšaj
nova_w = int(w * nova_velikost_faktor)
nova_h = int(h * nova_velikost_faktor)
if nova_w > 0 and nova_h > 0:
objekt = objekt.resize((nova_w, nova_h), Image.Resampling.LANCZOS)
# Generiraj ime datoteke
ime_brez_ext = os.path.splitext(ime_slike)[0]
if len(objekti) == 1:
# Če je samo en objekt, ne dodaj številke
novo_ime = f"{ime_brez_ext}.png"
else:
# Če je več objektov, dodaj številko (npr. drevo_1, drevo_2, ...)
novo_ime = f"{ime_brez_ext}_obj{idx+1:02d}.png"
# Ustvari podmapo za izvorno mapo
podinhodna_mapa = os.path.join(izhodna_mapa, os.path.basename(mapa_izvora))
if not os.path.exists(podinhodna_mapa):
os.makedirs(podinhodna_mapa)
# Shrani
pot_shranjevanja = os.path.join(podinhodna_mapa, novo_ime)
objekt.save(pot_shranjevanja)
print(f" 💾 Shranil: {novo_ime} ({nova_w}x{nova_h}px)")
except Exception as e:
print(f" ❌ Napaka pri {ime_slike}: {str(e)}")
import traceback
traceback.print_exc()
def procesiraj_vse_mape():
"""
Glavna funkcija - procesiraj vse mape.
"""
print("🚀 Začenjam ločevanje objektov in odstranjevanje zelenega ozadja...\n")
print(f"📂 Vhodne mape: {len(vhodne_mape)}")
print(f"📦 Izhodna mapa: {izhodna_mapa}")
print(f"📏 Faktor pomanjševanja: {nova_velikost_faktor} ({int(nova_velikost_faktor*100)}%)")
print(f"🔍 Minimalna velikost objekta: {min_velikost_objekta}px")
print(f"🟢 Odstranjujem zeleno ozadje: RGB{ZELENA_BARVA_RGB} ±{BARVA_TOLERANCA}\n")
print("=" * 70)
skupaj_slik = 0
skupaj_objektov = 0
for mapa in vhodne_mape:
if not os.path.exists(mapa):
print(f"⚠️ Mapa ne obstaja: {mapa}")
continue
print(f"\n📁 Obdelujem mapo: {os.path.basename(mapa)}")
print("-" * 70)
slike = [f for f in os.listdir(mapa) if f.endswith((".png", ".jpg", ".jpeg"))]
print(f" Najdenih {len(slike)} slik\n")
for ime in slike:
pot = os.path.join(mapa, ime)
procesiraj_sliko(pot, ime, mapa)
skupaj_slik += 1
print("\n" + "=" * 70)
print(f"✨ KONČANO! Obdelal {skupaj_slik} slik")
print(f"📂 Rezultati so v: {izhodna_mapa}")
print(f" Vsak objekt je shranjen v LOČENI datoteki!")
# Preveri, če imamo scipy (potreben za najdi_objekte)
try:
from scipy import ndimage
procesiraj_vse_mape()
except ImportError:
print("❌ NAPAKA: Potrebuješ scipy knjižnico!")
print(" Namesti z: pip install scipy numpy pillow")
print("\n Zaženi: pip install scipy")