80 lines
2.5 KiB
Python
80 lines
2.5 KiB
Python
#!/usr/bin/python2.4
|
|
|
|
"""A simple script to convert asset images to BMP files, that supports
|
|
RGBA image."""
|
|
|
|
import struct
|
|
import Image
|
|
import sys
|
|
|
|
infile = sys.argv[1]
|
|
outfile = sys.argv[2]
|
|
|
|
if not outfile.endswith(".bmp"):
|
|
print >> sys.stderr, "Warning: I'm expecting to write BMP files."
|
|
|
|
im = Image.open(infile)
|
|
if im.mode == 'RGB':
|
|
im.save(outfile)
|
|
elif im.mode == 'RGBA':
|
|
# Python Imaging Library doesn't write RGBA BMP files, so we roll
|
|
# our own.
|
|
|
|
BMP_HEADER_FMT = ("<" # little-endian
|
|
"H" # signature
|
|
"L" # file size
|
|
"HH" # reserved (set to 0)
|
|
"L" # offset to start of bitmap data)
|
|
)
|
|
|
|
BITMAPINFO_HEADER_FMT= ("<" # little-endian
|
|
"L" # size of this struct
|
|
"L" # width
|
|
"L" # height
|
|
"H" # planes (set to 1)
|
|
"H" # bit count
|
|
"L" # compression (set to 0 for minui)
|
|
"L" # size of image data (0 if uncompressed)
|
|
"L" # x pixels per meter (1)
|
|
"L" # y pixels per meter (1)
|
|
"L" # colors used (0)
|
|
"L" # important colors (0)
|
|
)
|
|
|
|
fileheadersize = struct.calcsize(BMP_HEADER_FMT)
|
|
infoheadersize = struct.calcsize(BITMAPINFO_HEADER_FMT)
|
|
|
|
header = struct.pack(BMP_HEADER_FMT,
|
|
0x4d42, # "BM" in little-endian
|
|
(fileheadersize + infoheadersize +
|
|
im.size[0] * im.size[1] * 4),
|
|
0, 0,
|
|
fileheadersize + infoheadersize)
|
|
|
|
info = struct.pack(BITMAPINFO_HEADER_FMT,
|
|
infoheadersize,
|
|
im.size[0],
|
|
im.size[1],
|
|
1,
|
|
32,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
0,
|
|
0)
|
|
|
|
f = open(outfile, "wb")
|
|
f.write(header)
|
|
f.write(info)
|
|
data = im.tostring()
|
|
for j in range(im.size[1]-1, -1, -1): # rows bottom-to-top
|
|
for i in range(j*im.size[0]*4, (j+1)*im.size[0]*4, 4):
|
|
f.write(data[i+2]) # B
|
|
f.write(data[i+1]) # G
|
|
f.write(data[i+0]) # R
|
|
f.write(data[i+3]) # A
|
|
f.close()
|
|
else:
|
|
print >> sys.stderr, "Don't know how to handle image mode '%s'." % (im.mode,)
|