from PIL import Image
import struct
import os
import re
import xml.etree.ElementTree as ET
#Generado por ChatGPT
def crop_and_resize_image(input_path, output_path, target_width, target_height):
# Abrir la imagen
image = Image.open(input_path)
# Obtener las dimensiones de la imagen original
original_width, original_height = image.size
# Calcular el recorte en la anchura
left = (original_width - target_width) // 2
right = (original_width + target_width) // 2
# Recortar la imagen manteniendo toda la altura
cropped_image = image.crop((left, 0, right, original_height))
# Redimensionar la imagen manteniendo la relación de aspecto
resized_image = cropped_image.resize((target_width, target_height))
# Guardar la imagen redimensionada
resized_image.save(output_path)
#El código de rgb565_convert está sacado del script de Frogtool (https://github.com/tzlion/frogtool)
def rgb565_convert(src_filename, dest_filename, dest_size=None):
try:
srcimage = Image.open(src_filename)
except (OSError, IOError):
print(f"! Failed opening image file {src_filename} for conversion")
return False
try:
dest_file = open(dest_filename, "wb")
except (OSError, IOError):
print(f"! Failed opening destination file {dest_filename} for conversion")
return False
# convert the image to RGB if it was not already
image = Image.new('RGB', srcimage.size, (0, 0, 0))
image.paste(srcimage, None)
if dest_size and image.size != dest_size:
image = image.resize(dest_size)
image_height = image.size[1]
image_width = image.size[0]
pixels = image.load()
if not pixels:
print(f"! Failed to load image from {src_filename}")
return False
for h in range(image_height):
for w in range(image_width):
pixel = pixels[w, h]
if not type(pixel) is tuple:
print(f"! Unexpected pixel type at {w}x{h} from {src_filename}")
return False
r = pixel[0] >> 3
g = pixel[1] >> 2
b = pixel[2] >> 3
rgb = (r << 11) | (g << 5) | b
dest_file.write(struct.pack('H', rgb))
dest_file.close()
return True
def anade_final(src_filename, nombre_archivo):
with open(src_filename, 'r+b') as file:
content = file.read()
nombre_archivo = nombre_archivo+'.zip'
# Agrega los dos ceros al final del contenido
content_with_zeros = content + b'\x00\x00\x00\x00' + nombre_archivo.encode() + b'\x00\x00'
# Escribe el contenido actualizado en el archivo binario
file.seek(0, os.SEEK_END) # Posicionarse al final del archivo
file.write(content_with_zeros)
file.flush() # Asegurarse de que los cambios se escriban sin cerrar el archivo
def obtener_descripcion_por_nombre_de_juego(nombre_juego, juegos_dict):
return juegos_dict.get(nombre_juego)
def cargar_juegos_descripciones(file_path):
juegos_dict = {}
tree = ET.parse(file_path)
root = tree.getroot()
for juego in root.findall('game'):
nombre_juego = juego.attrib['name']
descripcion = juego.find('description').text
caracteres_prohibidos = r'[<>:"/\\|?*]'
nombre_limpio = re.sub(caracteres_prohibidos, '', descripcion)
juegos_dict[nombre_juego] = nombre_limpio
return juegos_dict
def procesa_archivos(carpeta):
# Obtener el diccionario de juegos y descripciones
juegos_dict = cargar_juegos_descripciones('DataFrog_SF2000_FBA_v0.2.97.42_playable_no_dups.dat')
for archivo in os.scandir(carpeta):
nombre, extension = os.path.splitext(os.path.basename(archivo.path))
ruta = os.path.dirname(archivo.path)
mini = os.path.join(ruta, nombre+'_mini'+extension)
nombre_final = os.path.join(ruta, juegos_dict.get(nombre, 'Unknown') + '.zfb')
temporal = os.path.join(ruta, 'temp.raw')
print('Procesando '+nombre+' con extensión '+extension+' en la ruta '+ruta+' como '+nombre_final)
crop_and_resize_image(archivo.path, mini, target_width, target_height)
rgb565_convert(mini, temporal)
anade_final(temporal, nombre)
os.rename(temporal, nombre_final)
os.remove(mini)
# Ejemplo de uso
target_width = 144
target_height = 208
procesa_archivos('roms')