#-*- coding: UTF-8 -*- import sys import os import struct import math from enum import IntEnum from PIL import Image __all__ = ['Bitmap'] # https://en.wikipedia.org/wiki/BMP_file_format class BitmapFileHeader(object): StructureSize = 14 def __init__(self): self.size = 0 self.reserved1 = 0 self.reserved2 = 0 self.offset = 54 def read(self, fd): magic = fd.read(2) assert magic == b'BM' self.size = struct.unpack(' width: total -= w break used.append(w) w = width - total if w: used.append(w) dims = used total = 0 bmps = [] for w in dims: bmp = Bitmap(w, height) for y in range(height): bmp.rows[y].clear() bmp.rows[y].extend(self.rows[y][total:total + w]) total += w bmps.append(bmp) return bmps @staticmethod def concatVertical(bmps): width = 0 height = 0 for bmp in bmps: height += bmp.height if width == 0: width = bmp.width elif width != bmp.width: raise ValueError(f'Invalid image width {bmp.width}, requre {width}!') out_bmp = Bitmap(width, height) rows = out_bmp.rows rows.clear() for bmp in bmps: for row in bmp.rows: rows.append(row[:]) return out_bmp def splitVertical(self, dims=None): width, height = self.size if not dims: dims = [width] * (height // width) h = height % width if h: dims.append(h) else: used = [] total = 0 for h in dims: total += h if total > height: total -= h break used.append(h) h = height - total if h: used.append(h) dims = used total = 0 bmps = [] for h in dims: bmp = Bitmap(width, h) bmp.rows.clear() for row in self.rows[total:total + h]: bmp.rows.append(row[:]) total += h bmps.append(bmp) return bmps def flipHorizontal(self): width, height = self.size bmp = Bitmap(width, height) bmp.rows.clear() for row in self.rows: copy = row[:] copy.reverse() bmp.rows.append(copy) return bmp def flipVertical(self): width, height = self.size bmp = Bitmap(width, height) bmp.rows.clear() for row in reversed(self.rows): bmp.rows.append(row[:]) return bmp