UPD: Warning! This is not for production use. You can use it for learning purposes, but please be aware that this code was written when I was only starting to learn programming and it has some bugs related to incorrect generation of images of some resolutions. If you're searching for more robust solution for production, consider using graphic libraries such as PIL or see already mentioned library "construct" for low-level bitmap generation.
There is my implementation of 24-bit bitmap in Python 3:
from struct import pack
class Bitmap():
def __init__(s, width, height):
s._bfType = 19778 # Bitmap signature
s._bfReserved1 = 0
s._bfReserved2 = 0
s._bcPlanes = 1
s._bcSize = 12
s._bcBitCount = 24
s._bfOffBits = 26
s._bcWidth = width
s._bcHeight = height
s._bfSize = 26+s._bcWidth*3*s._bcHeight
s.clear()
def clear(s):
s._graphics = [(0,0,0)]*s._bcWidth*s._bcHeight
def setPixel(s, x, y, color):
if isinstance(color, tuple):
if x<0 or y<0 or x>s._bcWidth-1 or y>s._bcHeight-1:
raise ValueError('Coords out of range')
if len(color) != 3:
raise ValueError('Color must be a tuple of 3 elems')
s._graphics[y*s._bcWidth+x] = (color[2], color[1], color[0])
else:
raise ValueError('Color must be a tuple of 3 elems')
def write(s, file):
with open(file, 'wb') as f:
f.write(pack('<HLHHL',
s._bfType,
s._bfSize,
s._bfReserved1,
s._bfReserved2,
s._bfOffBits)) # Writing BITMAPFILEHEADER
f.write(pack('<LHHHH',
s._bcSize,
s._bcWidth,
s._bcHeight,
s._bcPlanes,
s._bcBitCount)) # Writing BITMAPINFO
for px in s._graphics:
f.write(pack('<BBB', *px))
for i in range((4 - ((s._bcWidth*3) % 4)) % 4):
f.write(pack('B', 0))
def main():
side = 520
b = Bitmap(side, side)
for j in range(0, side):
b.setPixel(j, j, (255, 0, 0))
b.setPixel(j, side-j-1, (255, 0, 0))
b.setPixel(j, 0, (255, 0, 0))
b.setPixel(j, side-1, (255, 0, 0))
b.setPixel(0, j, (255, 0, 0))
b.setPixel(side-1, j, (255, 0, 0))
b.write('file.bmp')
if __name__ == '__main__':
main()
struct
module. – Implacable