bitmap_converter.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #!/usr/bin/env python
  2. '''This script converts from any image type supported by
  3. Python imaging library to the RLE-encoded format used by
  4. NxWidgets.
  5. '''
  6. from PIL import Image
  7. def get_palette(img, maxcolors = 255):
  8. '''Returns a list of colors. If there are too many colors in the image,
  9. the least used are removed.
  10. '''
  11. img = img.convert("RGB")
  12. colors = img.getcolors(65536)
  13. colors.sort(key = lambda c: -c[0])
  14. return [c[1] for c in colors[:maxcolors]]
  15. def write_palette(outfile, palette):
  16. '''Write the palette (normal and hilight) to the output file.'''
  17. outfile.write('static const NXWidgets::nxwidget_pixel_t palette[BITMAP_PALETTESIZE] =\n');
  18. outfile.write('{\n')
  19. for i in range(0, len(palette), 4):
  20. outfile.write(' ');
  21. for r, g, b in palette[i:i+4]:
  22. outfile.write('MKRGB(%3d,%3d,%3d), ' % (r, g, b))
  23. outfile.write('\n');
  24. outfile.write('};\n\n')
  25. outfile.write('static const NXWidgets::nxwidget_pixel_t hilight_palette[BITMAP_PALETTESIZE] =\n');
  26. outfile.write('{\n')
  27. for i in range(0, len(palette), 4):
  28. outfile.write(' ');
  29. for r, g, b in palette[i:i+4]:
  30. r = min(255, r + 50)
  31. g = min(255, g + 50)
  32. b = min(255, b + 50)
  33. outfile.write('MKRGB(%3d,%3d,%3d), ' % (r, g, b))
  34. outfile.write('\n');
  35. outfile.write('};\n\n')
  36. def quantize(color, palette):
  37. '''Return the color index to closest match in the palette.'''
  38. try:
  39. return palette.index(color)
  40. except ValueError:
  41. # No exact match, search for the closest
  42. def distance(color2):
  43. return sum([(a - b)**2 for a, b in zip(color, color2)])
  44. return palette.index(min(palette, key = distance));
  45. def encode_row(img, palette, y):
  46. '''RLE-encode one row of image data.'''
  47. entries = []
  48. color = None
  49. repeats = 0
  50. for x in range(0, img.size[0]):
  51. c = quantize(img.getpixel((x, y)), palette)
  52. if c == color and repeats < 255:
  53. repeats += 1
  54. else:
  55. if color is not None:
  56. entries.append((repeats, color))
  57. repeats = 1
  58. color = c
  59. if color is not None:
  60. entries.append((repeats, color))
  61. return entries
  62. def write_image(outfile, img, palette):
  63. '''Write the image contents to the output file.'''
  64. outfile.write('static const NXWidgets::SRlePaletteBitmapEntry bitmap[] =\n');
  65. outfile.write('{\n');
  66. for y in range(0, img.size[1]):
  67. entries = encode_row(img, palette, y)
  68. row = ""
  69. for r, c in entries:
  70. if len(row) > 60:
  71. outfile.write(' ' + row + '\n')
  72. row = ""
  73. row += '{%3d, %3d}, ' % (r, c)
  74. row += ' ' * (73 - len(row))
  75. outfile.write(' ' + row + '/* Row %d */\n' % y)
  76. outfile.write('};\n\n');
  77. def write_descriptor(outfile, name):
  78. '''Write the public descriptor structure for the image.'''
  79. outfile.write('extern const struct NXWidgets::SRlePaletteBitmap g_%s =\n' % name)
  80. outfile.write('{\n')
  81. outfile.write(' CONFIG_NXWIDGETS_BPP,\n')
  82. outfile.write(' CONFIG_NXWIDGETS_FMT,\n')
  83. outfile.write(' BITMAP_PALETTESIZE,\n')
  84. outfile.write(' BITMAP_WIDTH,\n')
  85. outfile.write(' BITMAP_HEIGHT,\n')
  86. outfile.write(' {palette, hilight_palette},\n')
  87. outfile.write(' bitmap\n')
  88. outfile.write('};\n')
  89. if __name__ == '__main__':
  90. import sys
  91. import os.path
  92. if len(sys.argv) != 3:
  93. print "Usage: bitmap_converter.py source.png output.cxx"
  94. sys.exit(1)
  95. img = Image.open(sys.argv[1]).convert("RGB")
  96. outfile = open(sys.argv[2], 'w')
  97. palette = get_palette(img)
  98. outfile.write(
  99. '''
  100. /* Automatically NuttX bitmap file. */
  101. /* Generated from %(src)s by bitmap_converter.py. */
  102. #include <nxconfig.hxx>
  103. #include <crlepalettebitmap.hxx>
  104. #define BITMAP_WIDTH %(width)s
  105. #define BITMAP_HEIGHT %(height)s
  106. #define BITMAP_PALETTESIZE %(palettesize)s
  107. ''' % {'src': sys.argv[1], 'width': img.size[0], 'height': img.size[1],
  108. 'palettesize': len(palette)}
  109. )
  110. name = os.path.splitext(os.path.basename(sys.argv[1]))[0]
  111. write_palette(outfile, palette)
  112. write_image(outfile, img, palette)
  113. write_descriptor(outfile, name)