epd_bitmap.py
1 import digitalio 2 import busio 3 import board 4 from adafruit_epd.epd import Adafruit_EPD 5 from adafruit_epd.il0373 import Adafruit_IL0373 6 from adafruit_epd.il91874 import Adafruit_IL91874 # pylint: disable=unused-import 7 from adafruit_epd.il0398 import Adafruit_IL0398 # pylint: disable=unused-import 8 from adafruit_epd.ssd1608 import Adafruit_SSD1608 # pylint: disable=unused-import 9 from adafruit_epd.ssd1675 import Adafruit_SSD1675 # pylint: disable=unused-import 10 11 12 # create the spi device and pins we will need 13 spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) 14 ecs = digitalio.DigitalInOut(board.D10) 15 dc = digitalio.DigitalInOut(board.D9) 16 srcs = digitalio.DigitalInOut(board.D7) # can be None to use internal memory 17 rst = digitalio.DigitalInOut(board.D11) # can be None to not use this pin 18 busy = digitalio.DigitalInOut(board.D12) # can be None to not use this pin 19 20 # give them all to our driver 21 print("Creating display") 22 # display = Adafruit_SSD1608(200, 200, spi, # 1.54" HD mono display 23 # display = Adafruit_SSD1675(122, 250, spi, # 2.13" HD mono display 24 # display = Adafruit_IL91874(176, 264, spi, # 2.7" Tri-color display 25 # display = Adafruit_IL0373(152, 152, spi, # 1.54" Tri-color display 26 # display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display 27 # display = Adafruit_IL0398(400, 300, spi, # 4.2" Tri-color display 28 display = Adafruit_IL0373( 29 104, 30 212, 31 spi, # 2.13" Tri-color display 32 cs_pin=ecs, 33 dc_pin=dc, 34 sramcs_pin=srcs, 35 rst_pin=rst, 36 busy_pin=busy, 37 ) 38 39 # IF YOU HAVE A FLEXIBLE DISPLAY (2.13" or 2.9") uncomment these lines! 40 # display.set_black_buffer(1, False) 41 # display.set_color_buffer(1, False) 42 43 display.rotation = 0 44 45 FILENAME = "blinka154mono.bmp" 46 47 48 def read_le(s): 49 # as of this writting, int.from_bytes does not have LE support, DIY! 50 result = 0 51 shift = 0 52 for byte in bytearray(s): 53 result += byte << shift 54 shift += 8 55 return result 56 57 58 class BMPError(Exception): 59 pass 60 61 62 def display_bitmap(epd, filename): # pylint: disable=too-many-locals, too-many-branches 63 try: 64 f = open("/" + filename, "rb") 65 except OSError: 66 print("Couldn't open file") 67 return 68 69 print("File opened") 70 try: 71 if f.read(2) != b"BM": # check signature 72 raise BMPError("Not BitMap file") 73 74 bmpFileSize = read_le(f.read(4)) 75 f.read(4) # Read & ignore creator bytes 76 77 bmpImageoffset = read_le(f.read(4)) # Start of image data 78 headerSize = read_le(f.read(4)) 79 bmpWidth = read_le(f.read(4)) 80 bmpHeight = read_le(f.read(4)) 81 flip = True 82 83 print( 84 "Size: %d\nImage offset: %d\nHeader size: %d" 85 % (bmpFileSize, bmpImageoffset, headerSize) 86 ) 87 print("Width: %d\nHeight: %d" % (bmpWidth, bmpHeight)) 88 89 if read_le(f.read(2)) != 1: 90 raise BMPError("Not singleplane") 91 bmpDepth = read_le(f.read(2)) # bits per pixel 92 print("Bit depth: %d" % (bmpDepth)) 93 if bmpDepth != 24: 94 raise BMPError("Not 24-bit") 95 if read_le(f.read(2)) != 0: 96 raise BMPError("Compressed file") 97 98 print("Image OK! Drawing...") 99 100 rowSize = (bmpWidth * 3 + 3) & ~3 # 32-bit line boundary 101 102 for row in range(bmpHeight): # For each scanline... 103 if flip: # Bitmap is stored bottom-to-top order (normal BMP) 104 pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize 105 else: # Bitmap is stored top-to-bottom 106 pos = bmpImageoffset + row * rowSize 107 108 # print ("seek to %d" % pos) 109 f.seek(pos) 110 rowdata = f.read(3 * bmpWidth) 111 for col in range(bmpWidth): 112 b, g, r = rowdata[3 * col : 3 * col + 3] # BMP files store RGB in BGR 113 if r < 0x80 and g < 0x80 and b < 0x80: 114 epd.pixel(col, row, Adafruit_EPD.BLACK) 115 elif r >= 0x80 and g >= 0x80 and b >= 0x80: 116 pass # epd.pixel(row, col, Adafruit_EPD.WHITE) 117 elif r >= 0x80: 118 epd.pixel(col, row, Adafruit_EPD.RED) 119 except OSError: 120 print("Couldn't read file") 121 except BMPError as e: 122 print("Failed to parse BMP: " + e.args[0]) 123 finally: 124 f.close() 125 print("Finished drawing") 126 127 128 # clear the buffer 129 display.fill(Adafruit_EPD.WHITE) 130 display_bitmap(display, FILENAME) 131 display.display()