My Marlin configs for Fabrikator Mini and CTC i3 Pro B
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

bitmap2cpp.py 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #!/usr/bin/python
  2. # Written By Marcio Teixeira 2019 - Aleph Objects, Inc.
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # To view a copy of the GNU General Public License, go to the following
  15. # location: <http://www.gnu.org/licenses/>.
  16. from __future__ import print_function
  17. from PIL import Image
  18. import argparse
  19. import textwrap
  20. def pack_rle(data):
  21. """Use run-length encoding to pack the bytes"""
  22. rle = []
  23. value = data[0]
  24. count = 0
  25. for i in data:
  26. if i != value or count == 255:
  27. rle.append(count)
  28. rle.append(value)
  29. value = i
  30. count = 1
  31. else:
  32. count += 1
  33. rle.append(count)
  34. rle.append(value)
  35. return rle
  36. class WriteSource:
  37. def __init__(self, lines_in_blocks):
  38. self.blocks = []
  39. self.values = []
  40. self.block_size = lines_in_blocks
  41. self.rows = 0
  42. def add_pixel(self, value):
  43. self.values.append(value)
  44. def convert_to_4bpp(self, data, chunk_size = 0):
  45. # Invert the image
  46. data = map(lambda i: 255 - i, data)
  47. # Quanitize 8-bit values into 4-bits
  48. data = map(lambda i: i >> 4, data)
  49. # Make sure there is an even number of elements
  50. if (len(data) & 1) == 1:
  51. result.append(0)
  52. # Combine each two adjacent values into one
  53. i = iter(data)
  54. data = map(lambda a, b: a << 4 | b, i ,i)
  55. # Pack the data
  56. data = pack_rle(data)
  57. # Convert values into hex strings
  58. return map(lambda a: "0x" + format(a, '02x'), data)
  59. def end_row(self, y):
  60. # Pad each row into even number of values
  61. if len(self.values) & 1:
  62. self.values.append(0)
  63. self.rows += 1
  64. if self.block_size and (self.rows % self.block_size) == 0:
  65. self.blocks.append(self.values)
  66. self.values = []
  67. def write(self):
  68. if len(self.values):
  69. self.blocks.append(self.values)
  70. block_strs = [];
  71. for b in self.blocks:
  72. data = self.convert_to_4bpp(b)
  73. data = ', '.join(data)
  74. data = textwrap.fill(data, 75, initial_indent = ' ', subsequent_indent = ' ')
  75. block_strs.append(data)
  76. print("const unsigned char font[] PROGMEM = {")
  77. for i, b in enumerate(block_strs):
  78. if i:
  79. print(',')
  80. print('\n /* {} */'.format(i))
  81. print(b, end='')
  82. print("\n};")
  83. if __name__ == "__main__":
  84. parser = argparse.ArgumentParser(description='Converts a grayscale bitmap into a 16-level RLE packed C array for use as font data')
  85. parser.add_argument("input")
  86. parser.add_argument('--char_height', help='Adds a separator every so many lines', type=int)
  87. args = parser.parse_args()
  88. writer = WriteSource(args.char_height)
  89. img = Image.open(args.input).convert('L')
  90. for y in range(img.height):
  91. for x in range(img.width):
  92. writer.add_pixel(img.getpixel((x,y)))
  93. writer.end_row(y)
  94. writer.write()