The Android Open Source Project | c24a8e6 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 1 | #!/usr/bin/python2.4 |
| 2 | |
| 3 | """A simple script to convert asset images to BMP files, that supports |
| 4 | RGBA image.""" |
| 5 | |
| 6 | import struct |
| 7 | import Image |
| 8 | import sys |
| 9 | |
| 10 | infile = sys.argv[1] |
| 11 | outfile = sys.argv[2] |
| 12 | |
| 13 | if not outfile.endswith(".bmp"): |
| 14 | print >> sys.stderr, "Warning: I'm expecting to write BMP files." |
| 15 | |
| 16 | im = Image.open(infile) |
| 17 | if im.mode == 'RGB': |
| 18 | im.save(outfile) |
| 19 | elif im.mode == 'RGBA': |
| 20 | # Python Imaging Library doesn't write RGBA BMP files, so we roll |
| 21 | # our own. |
| 22 | |
| 23 | BMP_HEADER_FMT = ("<" # little-endian |
| 24 | "H" # signature |
| 25 | "L" # file size |
| 26 | "HH" # reserved (set to 0) |
| 27 | "L" # offset to start of bitmap data) |
| 28 | ) |
| 29 | |
| 30 | BITMAPINFO_HEADER_FMT= ("<" # little-endian |
| 31 | "L" # size of this struct |
| 32 | "L" # width |
| 33 | "L" # height |
| 34 | "H" # planes (set to 1) |
| 35 | "H" # bit count |
| 36 | "L" # compression (set to 0 for minui) |
| 37 | "L" # size of image data (0 if uncompressed) |
| 38 | "L" # x pixels per meter (1) |
| 39 | "L" # y pixels per meter (1) |
| 40 | "L" # colors used (0) |
| 41 | "L" # important colors (0) |
| 42 | ) |
| 43 | |
| 44 | fileheadersize = struct.calcsize(BMP_HEADER_FMT) |
| 45 | infoheadersize = struct.calcsize(BITMAPINFO_HEADER_FMT) |
| 46 | |
| 47 | header = struct.pack(BMP_HEADER_FMT, |
| 48 | 0x4d42, # "BM" in little-endian |
| 49 | (fileheadersize + infoheadersize + |
| 50 | im.size[0] * im.size[1] * 4), |
| 51 | 0, 0, |
| 52 | fileheadersize + infoheadersize) |
| 53 | |
| 54 | info = struct.pack(BITMAPINFO_HEADER_FMT, |
| 55 | infoheadersize, |
| 56 | im.size[0], |
| 57 | im.size[1], |
| 58 | 1, |
| 59 | 32, |
| 60 | 0, |
| 61 | 0, |
| 62 | 1, |
| 63 | 1, |
| 64 | 0, |
| 65 | 0) |
| 66 | |
| 67 | f = open(outfile, "wb") |
| 68 | f.write(header) |
| 69 | f.write(info) |
| 70 | data = im.tostring() |
| 71 | for j in range(im.size[1]-1, -1, -1): # rows bottom-to-top |
| 72 | for i in range(j*im.size[0]*4, (j+1)*im.size[0]*4, 4): |
| 73 | f.write(data[i+2]) # B |
| 74 | f.write(data[i+1]) # G |
| 75 | f.write(data[i+0]) # R |
| 76 | f.write(data[i+3]) # A |
| 77 | f.close() |
| 78 | else: |
| 79 | print >> sys.stderr, "Don't know how to handle image mode '%s'." % (im.mode,) |