class BMPImage: def __init__(self, data): self.data = data self._get_bmp_header() self._get_bmp_info_header() self._get_bmp_color_table() offset = self.header["offset"] self.BITMAP = memoryview(data[offset:]) self.HEIGHT = self.info_header["height"] self.WIDTH = self.info_header["width"] self.COLORS = self.info_header["colors_used"] self.BPP = self.info_header["bit_count"] # Bits per pixel self.PALLETTE = self.color_table def _get_bmp_header(self): d = self.data self.header = { "signature": d[0:2].decode("ascii"), "file_size": int.from_bytes(data[2:6], "little"), "offset": int.from_bytes(data[10:14], "little"), "header_size": int.from_bytes(data[14:18], "little"), } def _get_bmp_info_header(self): offset = 14 # BMP header size data = self.data[offset:] self.info_header = { "size": int.from_bytes(data[0:4], "little"), "width": int.from_bytes(data[4:8], "little"), "height": int.from_bytes(data[8:12], "little"), "planes": int.from_bytes(data[12:14], "little"), "bit_count": int.from_bytes(data[14:16], "little"), "compression": int.from_bytes(data[16:20], "little"), "image_size": int.from_bytes(data[20:24], "little"), "x_pixels_per_meter": int.from_bytes(data[24:28], "little"), "y_pixels_per_meter": int.from_bytes(data[28:32], "little"), "colors_used": int.from_bytes(data[32:36], "little"), "important_colors": int.from_bytes(data[36:40], "little"), } def _get_bmp_color_table(self): bpp = self.info_header["bit_count"] color_amount = self.info_header["colors_used"] if bpp > 8: self.color_table = [] return if color_amount == 0: color_amount = 2 ** bpp offset = 14 + 40 # File header + Info header data = self.data[offset:offset + color_amount * 4] self.color_table = [ int.from_bytes(data[i:i+4], "little") for i in range(0, len(data), 4) ]