Module: SimpleBMP

Defined in:
lib/simple_bmp.rb

Class Method Summary collapse

Class Method Details

.export(pixels, filename = "temp.bmp") ⇒ Object

export 2-dimensional array [height x width] of 0..255 for grayscale export 3-dimensional array [height x width x 3] of 0..255 for RGB we use BITMAPINFOHEADER (40 bytes), because BITMAPCOREHEADER (12 bytes) can’t 8bpp



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
# File 'lib/simple_bmp.rb', line 5

def self.export pixels, filename = "temp.bmp"
    bitmap_width = pixels.first.size
    bitmap_height = pixels.size
=begin
    hsv2bgr = lambda do |(h,s,v)|
        a = (v - vmin = (100-s)*v/100)*(h % 60)/60.0
        vinc, vdec = vmin + a, v - a
        case h/60
        when 0 ; [vmin, vinc, v]
        when 1 ; [vmin, v, vdec]
        when 2 ; [vinc, v, vmin]
        when 3 ; [v, vdec, vmin]
        when 4 ; [v, vmin, vinc]
        when 5 ; [vdec, vmin, v]
        end.map{ |i| (2.55 * i).floor }
    end
=end

    pixel_array = pixels.reverse.flat_map do |row|
        #row_bytes = row.map(&hsv2bgr).flatten
        row_bytes = row.flat_map{ |pixel| pixel.is_a?(Array) ? pixel : [pixel]*3 }
        row_bytes.fill 0, row_bytes.size .. (row_bytes.size + 3) / 4 * 4 - 1
    end
    file_size = 14 + 40 + pixel_array.size

    open(filename, "wb") do |file|
        # Bitmap file header (14 bytes)
        file.write ["BM", file_size, 14 + 40].pack "A2qi" # "A2QL"
        # DIB header (BITMAPINFOHEADER, 40 bytes)
        file.write [40, bitmap_width, bitmap_height, 1, 24].pack "LllSS"
        file.write [0, 0, 1, 1, 0, 0].pack "LLllLL"
        file.write pixel_array.pack "C*"
    end
end