116 lines
3.7 KiB
Python
116 lines
3.7 KiB
Python
import os
|
|
import sys
|
|
from PIL import Image
|
|
from processpalette import extractPaletteFromImage, palettes
|
|
from args import args
|
|
from assethelpers import getAssetRelativePath
|
|
from 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:
|
|
print(f"No matching palette found for {assetPath}!")
|
|
# Find which pixel is missing
|
|
for color in imagePalette:
|
|
if color not in palette:
|
|
print(f"Missing color: {color}")
|
|
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) |