bmp.py
· 2.2 KiB · Python
原始文件
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)
]
| 1 | class BMPImage: |
| 2 | def __init__(self, data): |
| 3 | self.data = data |
| 4 | self._get_bmp_header() |
| 5 | self._get_bmp_info_header() |
| 6 | self._get_bmp_color_table() |
| 7 | |
| 8 | offset = self.header["offset"] |
| 9 | |
| 10 | self.BITMAP = memoryview(data[offset:]) |
| 11 | self.HEIGHT = self.info_header["height"] |
| 12 | self.WIDTH = self.info_header["width"] |
| 13 | self.COLORS = self.info_header["colors_used"] |
| 14 | self.BPP = self.info_header["bit_count"] # Bits per pixel |
| 15 | self.PALLETTE = self.color_table |
| 16 | |
| 17 | def _get_bmp_header(self): |
| 18 | d = self.data |
| 19 | self.header = { |
| 20 | "signature": d[0:2].decode("ascii"), |
| 21 | "file_size": int.from_bytes(data[2:6], "little"), |
| 22 | "offset": int.from_bytes(data[10:14], "little"), |
| 23 | "header_size": int.from_bytes(data[14:18], "little"), |
| 24 | } |
| 25 | |
| 26 | def _get_bmp_info_header(self): |
| 27 | offset = 14 # BMP header size |
| 28 | data = self.data[offset:] |
| 29 | |
| 30 | self.info_header = { |
| 31 | "size": int.from_bytes(data[0:4], "little"), |
| 32 | "width": int.from_bytes(data[4:8], "little"), |
| 33 | "height": int.from_bytes(data[8:12], "little"), |
| 34 | "planes": int.from_bytes(data[12:14], "little"), |
| 35 | "bit_count": int.from_bytes(data[14:16], "little"), |
| 36 | "compression": int.from_bytes(data[16:20], "little"), |
| 37 | "image_size": int.from_bytes(data[20:24], "little"), |
| 38 | "x_pixels_per_meter": int.from_bytes(data[24:28], "little"), |
| 39 | "y_pixels_per_meter": int.from_bytes(data[28:32], "little"), |
| 40 | "colors_used": int.from_bytes(data[32:36], "little"), |
| 41 | "important_colors": int.from_bytes(data[36:40], "little"), |
| 42 | } |
| 43 | |
| 44 | |
| 45 | def _get_bmp_color_table(self): |
| 46 | bpp = self.info_header["bit_count"] |
| 47 | color_amount = self.info_header["colors_used"] |
| 48 | |
| 49 | if bpp > 8: |
| 50 | self.color_table = [] |
| 51 | return |
| 52 | |
| 53 | if color_amount == 0: |
| 54 | color_amount = 2 ** bpp |
| 55 | |
| 56 | offset = 14 + 40 # File header + Info header |
| 57 | data = self.data[offset:offset + color_amount * 4] |
| 58 | |
| 59 | self.color_table = [ |
| 60 | int.from_bytes(data[i:i+4], "little") |
| 61 | for i in range(0, len(data), 4) |
| 62 | ] |