File: WriteBMP.py

package info (click to toggle)
golly 3.2-2
  • links: PTS
  • area: main
  • in suites: buster
  • size: 19,516 kB
  • sloc: cpp: 69,819; ansic: 25,894; python: 7,921; sh: 4,267; objc: 3,721; java: 2,781; xml: 1,362; makefile: 530; perl: 69
file content (83 lines) | stat: -rw-r--r-- 3,102 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# Just to save the user having to install PIL.
# BMP code from: http://pseentertainmentcorp.com/smf/index.php?topic=2034.0
# Distributed with kind permission from James Main <jdmain@comcast.net>

import struct

def WriteBMP(pixels,filename):
    '''
    Write a BMP to filename from the (r,g,b) triples in pixels[row][column].

    Usage example:

    WriteBMP( [[(255,0,0),(0,255,0),(255,255,0)],[(0,0,255),(0,0,0),(0,255,255)]], "test.bmp" )
    '''
    # Here is a minimal dictionary with header values.
    d = {
        'mn1':66,
        'mn2':77,
        'filesize':0,
        'undef1':0,
        'undef2':0,
        'offset':54,
        'headerlength':40,
        'width':len(pixels[0]),
        'height':len(pixels),
        'colorplanes':1,
        'colordepth':24,
        'compression':0,
        'imagesize':0,
        'res_hor':0,
        'res_vert':0,
        'palette':0,
        'importantcolors':0
        }
    # Build the byte array.  This code takes the height
    # and width values from the dictionary above and
    # generates the pixels row by row.  The row_mod and padding
    # stuff is necessary to ensure that the byte count for each
    # row is divisible by 4.  This is part of the specification.
    bytes = ''
    for row in range(d['height']-1,-1,-1): # (BMPs are encoded left-to-right from the bottom-left)
        for column in range(d['width']):
            r,g,b = pixels[row][column]
            pixel = struct.pack('<BBB',b,g,r)
            bytes += pixel
        row_mod = (d['width']*d['colordepth']/8) % 4
        if row_mod == 0:
            padding = 0
        else:
            padding = (4 - row_mod)
        padbytes = ''
        for i in range(padding):
            x = struct.pack('<B',0)
            padbytes = padbytes + x
        bytes = bytes + padbytes
    # These header values are described in the bmp format spec.
    # You can find it on the internet. This is for a Windows
    # Version 3 DIB header.
    mn1 = struct.pack('<B',d['mn1'])
    mn2 = struct.pack('<B',d['mn2'])
    filesize = struct.pack('<L',d['filesize'])
    undef1 = struct.pack('<H',d['undef1'])
    undef2 = struct.pack('<H',d['undef2'])
    offset = struct.pack('<L',d['offset'])
    headerlength = struct.pack('<L',d['headerlength'])
    width = struct.pack('<L',d['width'])
    height = struct.pack('<L',d['height'])
    colorplanes = struct.pack('<H',d['colorplanes'])
    colordepth = struct.pack('<H',d['colordepth'])
    compression = struct.pack('<L',d['compression'])
    imagesize = struct.pack('<L',d['imagesize'])
    res_hor = struct.pack('<L',d['res_hor'])
    res_vert = struct.pack('<L',d['res_vert'])
    palette = struct.pack('<L',d['palette'])
    importantcolors = struct.pack('<L',d['importantcolors'])
    # create the outfile
    outfile = open(filename,'wb')
    # write the header + the bytes
    outfile.write(mn1+mn2+filesize+undef1+undef2+offset+headerlength+width+height+\
                  colorplanes+colordepth+compression+imagesize+res_hor+res_vert+\
                  palette+importantcolors+bytes)
    outfile.flush()
    outfile.close()