I'm trying to read a '.waltex' image, which is a 'walaber image'. It's basically just in raw image format. The problem is, it uses 'RGBA8888', 'RGBA4444', 'RGB565' and 'RGB5551' (all of which can be determined from the header), and I could not find a way to use these color specs in PIL.
I've tried doing this
from PIL import Image
with open('Carl.waltex', 'rb') as file:
rawdata = file.read()
image = Image.frombytes('RGBA', (1024,1024), rawdata, 'raw', 'RGBA;4B')
image.show()
I've tried all the 16-bit raw modes in the last input, and I couldn't find a single one that worked. To be clear, this file is specifically 'RGBA4444' with little endian, 8 bytes per pixel.
If you need the file, then I can link it.
Now that I have a better idea of how your Waltex files work, I attempted to write a custom PIL Plugin for them - a new experience for me. I've put it as a different answer because the approach is very different.
You use it very simply like this:
from PIL import Image
import WaltexImagePlugin
im = Image.open('objects.waltex')
im.show()
You need to save the following as WaltexImagePlugin.py
in the directory beside your main Python program:
from PIL import Image, ImageFile
import struct
def _accept(prefix):
return prefix[:4] == b"WALT"
class WaltexImageFile(ImageFile.ImageFile):
format = "Waltex"
format_description = "Waltex texture image"
def _open(self):
header = self.fp.read(HEADER_LENGTH)
magic, vers, fmt, w, h, _ = struct.unpack('4sBBHH6s', header)
# size in pixels (width, height)
self._size = w, h
# mode setting
self.mode = 'RGBA'
# Decoder
if fmt == 0:
# RGBA8888
# Just use built-in raw decoder
self.tile = [("raw", (0, 0) + self.size, HEADER_LENGTH, (self.mode,
0, 1))]
elif fmt == 3:
# RGBA4444
# Use raw decoder with custom RGBA;4B unpacker
self.tile = [("raw", (0, 0) + self.size, HEADER_LENGTH, ('RGBA;4B',
0, 1))]
Image.register_open(WaltexImageFile.format, WaltexImageFile, _accept)
Image.register_extensions(
WaltexImageFile.format,
[
".waltex"
],
)
HEADER_LENGTH = 16
It works perfectly for your RGBA888 images, but cannot quite handle the byte ordering of your RGBA444 file, so you need to reverse it for those images. I used this:
...
...
im = Image.open(...)
# Split channels and recombine in correct order
a, b, c, d = im.split()
im = Image.merge((c,d,a,b))
If anyone knows how to use something in the Unpack.c
file to do this correctly, please ping me. Thank you.