LoginSignup
3
2

More than 3 years have passed since last update.

nyagosでビットマップ表示

Posted at

nyagos.bmp.gif

エスケープシーケンスの背景色で描画してみた。
24bitカラーと8bitカラーだけ、パースも適当だけど・・・

環境はWindows10(1903) + Windows標準のコマンドプロンプト + nyagos

最初、1byteずつ読み込んでいたんだけど、どうも取りこぼしているようだったので
最初に全部読み込んでからパースしてます。

nyagos.alias.bmp = function(args)
  local bmp = io.open(args[1], 'r'):read('*a')

  -- Headr
  local p = 1
  p = p + 2 -- BM
  p = p + 4 -- File Size
  p = p + 2 -- Reserved
  p = p + 2 -- Reserved
  local offset = bmp:byte(p, p + 1)
  p = p+ 1
  offset = offset + bmp:byte(p, p + 1) * 0x100
  p = p + 1
  offset = offset + bmp:byte(p, p + 1) * 0x10000
  p = p + 1
  offset = offset + bmp:byte(p, p + 1) * 0x1000000
  p = p + 1
  p = p + 4 -- Info Header Size
  local width = bmp:byte(p, p + 1)
  p = p + 1
  width = width + bmp:byte(p, p + 1) * 0x100
  p = p + 1
  width = width + bmp:byte(p, p + 1) * 0x10000
  p = p + 1
  width = width + bmp:byte(p, p + 1) * 0x1000000
  p = p + 1
  local height = bmp:byte(p, p + 1)
  p = p + 1
  height = height + bmp:byte(p, p + 1) * 0x100
  p = p + 1
  height = height + bmp:byte(p, p + 1) * 0x10000
  p = p + 1
  height = height + bmp:byte(p, p + 1) * 0x1000000
  p = p + 1
  p = p + 2 -- Plane. always 1
  local bits = bmp:byte(p, p + 1)
  p = p + 1
  bits = bits + bmp:byte(p, p + 1) * 0x100
  p = p + 1
  local is24bit = false
  local is8bit = false
  if bits == 24 then
    is24bit = true
  elseif bits == 8 then
    is8bit = true
  else
    print("Unsupported format")
    return
  end
  p = p + 4 -- Compress
  p = p + 4 -- Data Size
  p = p + 4 -- Resolution
  p = p + 4 -- Resolution
  local palleteSize = bmp:byte(p, p + 1)
  p = p + 1
  palleteSize = palleteSize + bmp:byte(p, p + 1) * 0x100
  p = p + 1
  palleteSize = palleteSize + bmp:byte(p, p + 1) * 0x10000
  p = p + 1
  palleteSize = palleteSize + bmp:byte(p, p + 1) * 0x1000000
  p = p + 1
  p = p + 4 -- Important Color
  local pallete = {}
  for i = 1, palleteSize, 1 do
    pallete[i] = {}
    pallete[i][1] = bmp:byte(p, p + 1);
    p = p + 1
    pallete[i][2] = bmp:byte(p, p + 1);
    p = p + 1
    pallete[i][3] = bmp:byte(p, p + 1);
    p = p + 1
    pallete[i][4] = bmp:byte(p, p + 1);
    p = p + 1
  end
  p = offset + 1

  -- Data
  local img = {}
  for j = 1, height, 1 do
    img[height-j+1] = {}
    local r, g, b
    for i = 1, width, 1 do
      if is24bit then
        b = bmp:byte(p, p + 1)
        p = p + 1
        g = bmp:byte(p, p + 1)
        p = p + 1
        r = bmp:byte(p, p + 1)
        p = p + 1
      elseif is8bit then
        local pp = bmp:byte(p, p + 1)
        p = p + 1
        if pp ~= nil then
          b = pallete[pp + 1][1]
          g = pallete[pp + 1][2]
          r = pallete[pp + 1][3]
        end
      end
      img[height-j+1][i] = '\027[48;2;' .. r .. ';' .. g .. ';' .. b .. 'm  \027[49m'
    end
    -- padding
    if is24bit then
      p = p + width % 4
    elseif is8bit then
      p = p + (width * 3) % 4
    end
  end
  for _, r in pairs(img) do
    for _, c in pairs(r) do
      nyagos.write(c)
    end
    nyagos.write('\n')
  end
end
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2