# Converts digits.png to C code # # Image requirements: # White pixels are considered "lit" on the OLED, black not. Height must be a # multiple of 8. # # Each digit is assumed to be connected and needs to be separated by at least one vertical # white line. The maximum character width is used for all characters. AAll characters are # center-aligned to the maximum width. # # The output is arranged left-to-right, top-to-bottom, where each byte represents a column # of 8 pixels. This corresponds to the page addressing mode used by the SSD1306xled library. # # Library requirements: # Pillow (pip install pillow) # from __future__ import print_function from PIL import Image import math InputFile = "digits.png" OutputFile = "..\src\digits.h" # Open image and convert to black and white image = Image.open(InputFile).convert("L") width, height = image.size if height % 8 != 0: print("Error: height must be a multiple of 8") exit(1) pixels = image.load() def isEmptyColumn(x): for y in range(height): if pixels[x, y] != 0: return False return True def getColumnValue(x, y): value = 0 for yPos in range(8): if pixels[x, y + yPos] != 0: value = value | (1<= width: break startX = x while x < width and not isEmptyColumn(x): x += 1 digitWidth = x - startX if digitWidth > maxWidth: maxWidth = digitWidth digits.append({ "start": startX, "stop": x, "width": digitWidth }) x += 1 if len(digits) != 10: print("Error: expected 10 digits, found", len(digits)) exit(2) rows = int(math.ceil(height / 8)) print("Found 10 digits") print(" character width :", maxWidth) print(" rows per character :", rows) print(" total bytes :", rows * maxWidth * 10) output = open(OutputFile, "w") output.write("#ifndef __Digits\n") output.write("#define __Digits\n") output.write("\n") output.write("#include \n") output.write("\n") output.write("#define DigitWidth " + str(maxWidth) + "\n") output.write("#define DigitHeight " + str(height) + "\n") output.write("#define DigitRows " + str(rows) + "\n") output.write("#define DigitBytesPerChar " + str(rows * maxWidth) + "\n") output.write("\n\n\n") output.write("const uint8_t Digits[] PROGMEM = {\n") def outputColumn(value, isLast): output.write("0x{:02x}".format(value)) if not isLast: output.write(", ") # Generate byte array for each digit for digitIndex in range(len(digits)): digit = digits[digitIndex] output.write(" // " + str(digitIndex) + "\n") paddingLeft = int(math.floor((maxWidth - digit["width"]) / 2)) paddingRight = maxWidth - digit["width"] - paddingLeft for rowIndex in range(rows): lastRow = digitIndex == len(digits) - 1 and rowIndex == rows - 1 output.write(" ") # Add padding to center align the character for paddingIndex in range(paddingLeft): outputColumn(0, False) # Output one column at a time for x in range(digit["start"], digit["stop"]): outputColumn(getColumnValue(x, rowIndex * 8), lastRow and paddingRight == 0 and x == digit["stop"] - 1) for paddingIndex in range(paddingRight): outputColumn(0, lastRow and paddingIndex == paddingRight - 1) output.write("\n") output.write("\n") output.write("};\n") output.write("\n") output.write("#endif\n") output.close() print("") print("Wrote output to", OutputFile)