Kitomas

bmp24.lua

Aug 1st, 2021
956
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --saves a 24 bit uncompressed bmp based
  2. --on a 2d table of {r,g,b} indices
  3. --(each channel's value should be no
  4. --more than 255, of course)
  5. function bmp24(map,path)
  6.   --parse parameters:
  7.   if type(map) ~= 'table' then
  8.     return nil,'Map parameter is not table'
  9.   end
  10.   if path and type(path) ~= 'string' then
  11.     return nil,'Path parameter exists, but is not string'
  12.   end
  13.   path=path or '/'..shell.dir()..'/untitled.bmp'
  14.   --idiot check to see if rows are same len:
  15.   local idiot=false
  16.   local temp=0
  17.   local temp2=math.huge
  18.   for iy,mr in ipairs(map) do
  19.     if #mr > temp then temp=#mr end
  20.     if temp2 < temp then
  21.       idiot=true break end
  22.     temp2=#mr
  23.   end
  24.   if idiot then --if idiot then add magenta to missing columns
  25.     for iy,mr in ipairs(map) do
  26.       while #mr < temp do
  27.         mr[#mr+1]={255,0,255}
  28.       end
  29.     end
  30.   end
  31.   --open file and write header
  32.   local function littleEnd(num)
  33.     if num==0 then return {'00'} end
  34.     local bEnd=string.format("%x",num)
  35.     if #bEnd%2 == 1 then bEnd='0'..bEnd end
  36.     local lEnd={}
  37.     for i=1,#bEnd,2 do lEnd[#lEnd+1]=bEnd:sub(i,i+1) end
  38.     local fl=0
  39.     for i=1,math.floor(#lEnd/2) do
  40.       fl=#lEnd-i+1
  41.       lEnd[i],lEnd[fl]=lEnd[fl],lEnd[i]
  42.     end
  43.     return lEnd
  44.   end
  45.   local function fillTab(tab,to)
  46.     while #tab < to do tab[#tab+1]='00' end
  47.     return tab
  48.   end
  49.   local file=io.open(path,'wb')
  50.    --file signature:2 bytes, big
  51.   file:write(66)--"B"
  52.   file:write(77)--"M"
  53.   local rowPadding=(4-(3*#map[1])%4)%4 --wow i probably did that badly but i dont care
  54.   local fileSize=54+(3*#map[1]*#map)+(rowPadding*#map)
  55.    --file size: 4 bytes, little
  56.   for i,v in ipairs(fillTab(littleEnd(fileSize),4)) do--lol
  57.     file:write(tonumber(v,16)) end
  58.    --reserved: 4 bytes, doesn't matter it's just zero lol
  59.   for i=1,4 do file:write(0) end
  60.    --bitmap data offset: 4 bytes, little
  61.   file:write(54)
  62.   for i=1,3 do file:write(0) end
  63.    --infoheader size: 4 bytes, little
  64.   file:write(40)
  65.   for i=1,3 do file:write(0) end
  66.    --image width: 4 bytes, little
  67.   for i,v in ipairs(fillTab(littleEnd(#map[1]),4)) do
  68.     file:write(tonumber(v,16)) end
  69.    --image height: 4 bytes, little
  70.   for i,v in ipairs(fillTab(littleEnd(#map),4)) do
  71.     file:write(tonumber(v,16)) end
  72.    --number of planes: 2 bytes, little
  73.   file:write(1)
  74.   file:write(0)
  75.    --number of bits per pixel: 2 bytes, little
  76.   file:write(24)
  77.   file:write(0)
  78.    --compression type: 4 bytes, little
  79.    --compressed image size: 4 bytes, little
  80.    --x pixels per meter: 4 bytes, little
  81.    --y pixels per meter: 4 bytes, little
  82.    --used colors:4 bytes, little
  83.    --important colors: 4 bytes, little
  84.   for i=1,24 do file:write(0) end
  85.   --write pixel data
  86.   for iy=#map,1,-1 do
  87.     for ix=1,#map[iy] do
  88.       for ic=3,1,-1 do
  89.         file:write(map[iy][ix][ic])
  90.       end
  91.     end
  92.     if rowPadding > 0 then
  93.       for i=1,rowPadding do
  94.         file:write(0)
  95.       end
  96.     end
  97.   end
  98.   file:close()
  99.   return true --it's finally over
  100. end
  101. --hopefully the below line works with require if uncommented
  102. --return bmp24
  103. --[[
  104. --i used below for testing
  105. local bmap={}
  106. local count=255
  107. local op=-1
  108. local res={16,16}
  109. for iy=1,res[2] do
  110.   bmap[#bmap+1]={}
  111.   for ix=1,res[1] do
  112.     bmap[iy][#bmap[iy]+1]={count,count,count}
  113.     count=count+op
  114.   end
  115.   --this line tests the uneven rows failsafe
  116.   if iy==res[2] then bmap[iy][#bmap[iy]+1]={255,0,0} end
  117.   bmap[#bmap+1]=row
  118. end
  119. bmp24(bmap)
  120. --]]
  121.  
RAW Paste Data