Skip to content

Instantly share code, notes, and snippets.

@jbgutierrez
Created December 16, 2025 15:31
Show Gist options
  • Select an option

  • Save jbgutierrez/b9fe7b9c1dc449cc12c0bdd9f1f255cb to your computer and use it in GitHub Desktop.

Select an option

Save jbgutierrez/b9fe7b9c1dc449cc12c0bdd9f1f255cb to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
"""
Script para generar siluetas PNG a partir de PSD.
Extrae la máscara de la capa "PNG" y la exporta.
"""
import sys
from pathlib import Path
from PIL import Image, ImageOps
from psd_tools import PSDImage
def generate_silhouette(psd_path: str, output_path: str = None) -> str:
"""
Genera una silueta PNG a partir de un PSD.
Args:
psd_path: Ruta del archivo PSD
output_path: Ruta de salida (opcional, por defecto reutiliza el nombre del PSD)
Returns:
Ruta del archivo PNG generado
"""
psd_path = Path(psd_path)
if not psd_path.exists():
raise FileNotFoundError(f"PSD no encontrado: {psd_path}")
# Abrir el PSD
psd = PSDImage.open(psd_path)
# Si no se especifica salida, usar la misma ruta pero con extensión .png
if output_path is None:
output_path = psd_path.with_suffix('.png')
else:
output_path = Path(output_path)
print(f"📂 Abriendo: {psd_path}")
print(f"📏 Tamaño: {psd.width}x{psd.height}")
# Buscar la capa "PNG"
png_layer = None
for layer in psd:
if layer.name == "PNG":
png_layer = layer
break
if png_layer is None:
raise ValueError("No se encontró la capa 'PNG' en el PSD")
print(f"🎨 Capa PNG encontrada")
# Extraer la máscara de la capa PNG
if not png_layer.has_mask():
raise ValueError("La capa 'PNG' no tiene máscara")
# Obtener la máscara
mask = png_layer.mask
print(f"🎭 Máscara extraída: {mask.width}x{mask.height}")
# Convertir la máscara a imagen PIL
mask_image = mask.topil()
# Asegurar que sea RGBA para transparencia
if mask_image.mode != 'RGBA':
# Si es L (escala de grises), convertir a RGBA
# Los píxeles negros (0) serán transparentes, los blancos (255) opacos
mask_image = mask_image.convert('L')
# Crear imagen RGBA con fondo transparente
png_image = Image.new('RGBA', mask_image.size, (0, 0, 0, 0))
# Copiar solo donde la máscara es blanca (255)
png_image.putalpha(mask_image)
else:
png_image = mask_image.copy()
# Guardar la silueta
png_image.save(output_path, 'PNG')
print(f"✅ Silueta generada: {output_path}")
print(f" Modo: {png_image.mode}, Tamaño: {png_image.size}")
return str(output_path)
def process_directory(directory: str, pattern: str = "*.psd") -> list:
"""
Procesa todos los PSD en un directorio.
Args:
directory: Directorio a procesar
pattern: Patrón de búsqueda (default: "*.psd")
Returns:
Lista de archivos PNG generados
"""
directory = Path(directory)
generated_files = []
psd_files = list(directory.glob(pattern))
print(f"📁 Encontrados {len(psd_files)} archivos PSD en {directory}")
for psd_file in psd_files:
try:
output = generate_silhouette(str(psd_file))
generated_files.append(output)
except Exception as e:
print(f"❌ Error procesando {psd_file.name}: {e}")
return generated_files
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Uso:")
print(" python3 generate_silhouette.py <archivo.psd> [salida.png]")
print(" python3 generate_silhouette.py --dir <directorio>")
sys.exit(1)
if sys.argv[1] == "--dir":
directory = sys.argv[2] if len(sys.argv) > 2 else "."
generated = process_directory(directory)
print(f"\n✅ Se generaron {len(generated)} siluetas")
else:
psd_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else None
generate_silhouette(psd_file, output_file)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment