Files
dusk/tools/assetstool/processimage.py
Dominic Masters d788de8637
Some checks failed
Build Dusk / run-tests (push) Successful in 1m56s
Build Dusk / build-linux (push) Successful in 1m44s
Build Dusk / build-psp (push) Failing after 1m35s
Starting refactor of tools, thank gosh
2026-01-25 21:07:31 -06:00

120 lines
4.0 KiB
Python

import os
import sys
from PIL import Image
from tools.assetstool.processpalette import extractPaletteFromImage, palettes
from tools.assetstool.args import args
from tools.assetstool.assethelpers import getAssetRelativePath
from tools.assetstool.assetcache import assetGetCache, assetCache
images = []
def processImage(asset):
cache = assetGetCache(asset['path'])
if cache is not None:
return cache
type = None
if 'type' in asset['options']:
type = asset['options'].get('type', 'PALETTIZED').upper()
if type == 'PALETTIZED' or type is None:
return assetCache(asset['path'], processPalettizedImage(asset))
elif type == 'ALPHA':
return assetCache(asset['path'], processAlphaImage(asset))
else:
print(f"Error: Unknown image type {type} for asset {asset['path']}")
sys.exit(1)
def processPalettizedImage(asset):
assetPath = asset['path']
cache = assetGetCache(assetPath)
if cache is not None:
return cache
image = Image.open(assetPath)
imagePalette = extractPaletteFromImage(image)
# Find palette that contains every color
for palette in palettes:
if all(color in palette['pixels'] for color in imagePalette):
break
else:
palette = palettes[0] # Just to avoid reference error
print(f"No matching palette found for {assetPath}!")
# Find which pixel is missing
for color in imagePalette:
if color in palette['pixels']:
continue
# Convert to hex (with alpha)
hexColor = '#{:02x}{:02x}{:02x}{:02x}'.format(color[0], color[1], color[2], color[3])
print(f"Missing color: {hexColor} in palette {palette['paletteName']}")
sys.exit(1)
print(f"Converting image {assetPath} to use palette")
paletteIndexes = []
for pixel in list(image.getdata()):
if pixel[3] == 0:
pixel = (0, 0, 0, 0)
paletteIndex = palette['pixels'].index(pixel)
paletteIndexes.append(paletteIndex)
data = bytearray()
data.extend(b"DPI") # Dusk Palettized Image
data.extend(image.width.to_bytes(4, 'little')) # Width
data.extend(image.height.to_bytes(4, 'little')) # Height
data.append(palette['paletteIndex']) # Palette index
for paletteIndex in paletteIndexes:
if paletteIndex > 255 or paletteIndex < 0:
print(f"Error: Palette index {paletteIndex} exceeds 255!")
sys.exit(1)
data.append(paletteIndex.to_bytes(1, 'little')[0]) # Pixel index
relative = getAssetRelativePath(assetPath)
fileNameWithoutExt = os.path.splitext(os.path.basename(assetPath))[0]
outputFileRelative = os.path.join(os.path.dirname(relative), f"{fileNameWithoutExt}.dpi")
outputFilePath = os.path.join(args.output_assets, outputFileRelative)
os.makedirs(os.path.dirname(outputFilePath), exist_ok=True)
with open(outputFilePath, "wb") as f:
f.write(data)
outImage = {
"imagePath": outputFileRelative,
"files": [ outputFilePath ],
'width': image.width,
'height': image.height,
}
return assetCache(assetPath, outImage)
def processAlphaImage(asset):
assetPath = asset['path']
cache = assetGetCache(assetPath)
if cache is not None:
return cache
print(f"Processing alpha image: {assetPath}")
data = bytearray()
data.extend(b"DAI") # Dusk Alpha Image
image = Image.open(assetPath).convert("RGBA")
data.extend(image.width.to_bytes(4, 'little')) # Width
data.extend(image.height.to_bytes(4, 'little')) # Height
for pixel in list(image.getdata()):
# Only write alpha channel
data.append(pixel[3].to_bytes(1, 'little')[0]) # Pixel alpha
relative = getAssetRelativePath(assetPath)
fileNameWithoutExt = os.path.splitext(os.path.basename(assetPath))[0]
outputFileRelative = os.path.join(os.path.dirname(relative), f"{fileNameWithoutExt}.dai")
outputFilePath = os.path.join(args.output_assets, outputFileRelative)
os.makedirs(os.path.dirname(outputFilePath), exist_ok=True)
with open(outputFilePath, "wb") as f:
f.write(data)
outImage = {
"imagePath": outputFileRelative,
"files": [ outputFilePath ],
'width': image.width,
'height': image.height,
}
return assetCache(assetPath, outImage)