module SimpleBMP
Currently there are no need of classes – just a single public module method.
Export only to BITMAPCOREHEADER (12 bytes), because it’s enough. Import BITMAPCOREHEADER and 24bpp BITMAPINFOHEADER because MS Paint uses it.
Public Class Methods
enlarge(array, **args)
click to toggle source
Truncated box modal resizing
# File lib/simple_bmp.rb, line 74 def self.enlarge array, **args array = array.flat_map{ |row| [ row.flat_map{ |cell| [cell] * args[:times] } ] * args[:times] } end
export(pixels, filename = "temp.bmp")
click to toggle source
+pixels+ is either two or three dimensional array:
[height x width x 3] of 0..255 for RGB [height x width] of 0..255 for grayscale
Two-dimensional will be processed as it’s three, where R, G anb B are equal.
Examples of exporting a single pixel image which is almost gray:
export [[100]], "temp.bmp" export [[[90,100,110]]], "temp.bmp"
# File lib/simple_bmp.rb, line 19 def self.export pixels, filename = "temp.bmp" #fail "pixel array shouldn't be empty" if pixels.empty? fail "all pixel array rows should be of the same length" if pixels.map(&:size).uniq.size != 1 bitmap_width = pixels.first.size bitmap_height = pixels.size 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.reverse : [pixel]*3 } row_bytes.fill 0, row_bytes.size .. @@align4[row_bytes.size] - 1 end # 12=>BITMAPCOREHEADER, 40=>BITMAPINFOHEADER dib_header_size = 12 file_size = 14 + dib_header_size + pixel_array.size open(filename, "wb") do |file| # Bitmap file header file.write ["BM", file_size, 14 + dib_header_size].pack "A2qi" # "A2QL" # DIB header # file.write [dib_header_size, bitmap_width, bitmap_height, 1, 24].pack "LllSS" # file.write [0, 0, 1, 1, 0, 0].pack "LLllLL" # BITMAPINFOHEADER file.write [dib_header_size, bitmap_width, bitmap_height, 1, 24].pack "LSSSS" file.write pixel_array.pack "C*" end end
import(filename = "temp.bmp")
click to toggle source
This imports BITMAPCOREHEADER and 24bpp BITMAPINFOHEADER headed RGB bmp images returning a 3-dimentional array.
# File lib/simple_bmp.rb, line 47 def self.import filename = "temp.bmp" File.open(filename, "rb") do |file| _, _, shift = file.read(14).unpack("A2qi") dib_header_size, = file.read(4).unpack("L") case dib_header_size when 12 ; bitmap_width, bitmap_height = file.read(4).unpack("SS") when 40 ; bitmap_width, bitmap_height = file.read(8).unpack("ii") else ; fail "can import only BITMAPCOREHEADER (12 bytes) and 24bpp BITMAPINFOHEADER (40 bytes)" end file.pos = shift (file.read(bitmap_height * @@align4[bitmap_width * 3]).unpack("C*")). each_slice(@@align4[bitmap_width * 3]).map do |row| row.each_slice(3).take(bitmap_width).map(&:reverse) end.reverse end end
reduce(array, **args)
click to toggle source
Truncated box modal resizing
# File lib/simple_bmp.rb, line 65 def self.reduce array, **args array = array.each_slice(args[:times]).take(array.size/args[:times]).map{ |rows| rows.transpose.each_slice(args[:times]).take(array.first.size/args[:times]).map{ |cells| cells.flatten(1).group_by{ |i| i }.sort_by{ |i,g| g.size }.last.first } } end