Toggle Navigation
Hatchery
Eggs
bmp_reader
__init__.py
Users
Badges
Login
Register
MCH2022 badge?
go to mch2022.badge.team
__init__.py
raw
Content
''' Script written by d4g Build upon original script by stuartm2 (https://github.com/stuartm2/CircuitPython_BMP_Reader/tree/master/lib) But refactored and optimized regarding memory consumption and merged into one file. How To Use: - copy file to /apps/bmp_reader/ - place images into /apps/bmp_reader/res/ - images have to be 24 bit bitmaps with the size 179x79 or less - use right buttons to cycle through images Display Size 179x79 ''' import gc import display import buttons import os class BMPReader(object): def __init__(self, filename): self._filename = filename self._read_img_header() with open(self._filename, 'rb') as f: self.f = bytes(f.read()) def do_pixels(self): width = self.width # line length must be a multiple of 4 # with the bitmask, the alignment is enforced with display.open() as d: d.clear() d.update() for line in range(self.height): # align image pitch = int(( (self.width * 3) +3 ) & 0xFFFFFFFC) start = self.start_pos + line * pitch pixel_data = bytes(self.f[start:start+self.width*3]) i = 0 t = len(pixel_data) while True: r = b = g = -1 try: i += 1 r = pixel_data[t - i] i += 1 g = pixel_data[t - i] i += 1 b = pixel_data[t - i] if i > t: break d.pixel(int(self.width - int(i/3)) , self.height - line ,col=(r,g,b)) except: # Somethin went wrong print('FOOO r: %s g: %s b: %s' % (r,g,b)) break d.update() gc.collect() return def _read_img_header(self): def _lebytes_to_int(bytes): n = 0x00 while len(bytes) > 0: n <<= 8 n |= bytes.pop() return int(n) with open(self._filename, 'rb') as f: img_bytes = list(bytearray(f.read(38))) assert img_bytes[0:2] == [66, 77], "Not a valid BMP file" # scan for compression assert _lebytes_to_int(img_bytes[30:34]) == 0, \ "Compression is not supported" # read color depth assert _lebytes_to_int(img_bytes[28:30]) == 24, \ "Only 24-bit colour depth is supported" # determin where the image data lies self.start_pos = _lebytes_to_int(img_bytes[10:14]) self.end_pos = self.start_pos + _lebytes_to_int(img_bytes[34:38]) # read width and height self.width = _lebytes_to_int(img_bytes[18:22]) self.height = _lebytes_to_int(img_bytes[22:26]) print ("height %s, width %s, start_pos %s, end_pos %s" % (self.height, self.width, self.start_pos, self.end_pos)) #img = BMPReader('/apps/bmp_reader/image.bmp') def display_bmp(filename): gc.collect() print("Attempting to display %s" % filename) print("Mem: %s" % gc.mem_free()) img = BMPReader(filename) img.do_pixels() del img print("Mem: %s" % gc.mem_free()) gc.enable() gc.collect() print("Mem: %s" % gc.mem_free()) bmps = os.listdir("/apps/bmp_reader/res") imgc = len(bmps) print("Images: %s" % imgc) i = 0 display_bmp("/apps/bmp_reader/res/%s" % bmps[i]) while True: pressed = buttons.read( buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT ) if pressed != 0: if i < (imgc - 1): i += 1 else: i = 0 display_bmp("/apps/bmp_reader/res/%s" % bmps[i])