zoukankan      html  css  js  c++  java
  • Lua生成位图—string.pack打包数据的应用

      1 #! /usr/bin/env lua
      2 -- fileheader 14bytes
      3 -- infoheader 40bytes
      4 -- 数据用小端储存方式
      5 -- local fileheader = 
      6 -- {
      7 --     bfType = 2 byte,
      8 --     bfSize = 4 byte,
      9 --     bfReserved1 = 2 byte, must = 0,
     10 --     bfReserved2 = 2 byte, must = 0,
     11 --     bfOffBits = 4 byte,    
     12 
     13 -- }
     14 -- local infoheader = 
     15 -- {
     16 --     biSize = 4 byte, default = 40,
     17 --     biWidth  = 4 byte,
     18 --     biHeight  = 4 byte,
     19 --     biPlanes = 2 byte, must =1,
     20 --     biBitCount = 2 byte , 1/4/8/24/32
     21 --     bitCompression = 4 byte
     22 --     biSizeImage = 4 byte
     23 --     biXPelsPerMeter = 4 byte    
     24 --     biYPelsPerMeter = 4 byte
     25 --     biClrUsed  = 4 byte 
     26 --     biClrImortant = 4 byte
     27 -- }
     28 
     29 local BMP = {}
     30 function BMP:new( ... )
     31     local biBitCount = 24                -- 24bit/像素,也就是3byte/像素
     32     local biWidth = 256                  -- 默认256像素宽
     33     local biHeight = 256                 -- 默认256像素高
     34     local message  = string.format("生成24位位图,大小为 %d * %d ...",biWidth,biHeight)
     35     print(message)
     36     --  生成FHeader
     37     self:createFHeader(biWidth,biHeight,biBitCount)    
     38     --  生成IHeader
     39     self:createIHeader(biWidth,biHeight,biBitCount)
     40     local fname = "bmp_" .. os.date("%X"):gsub(":","") .. ".bmp"
     41     local file = io.open(fname,"wb")
     42     file:write(self.fheader)
     43     file:write(self.iheader)
     44     --  生成图像数据的方法,都是生成self.data(256*256的矩阵)
     45     local arg = { ... }
     46     --  空,随机生成各个像素点
     47     if not next(arg) then
     48         self:creatRandomData()
     49     else
     50         self:creatRandomMap()
     51     end
     52 
     53     if self.data then
     54         file:write(self.data)
     55     end
     56     file:close()
     57     os.execute("open " .. fname)  
     58 
     59     -- --  调用图像数据生成函数
     60     -- local bmp_data = self:creatSingleton()
     61     -- local function testBMP()
     62     --     local file = io.open("bmp.bmp","wb")
     63     --     file:write(self.fheader)
     64     --     file:write(self.iheader)
     65     --     file:write(bmp_data)
     66     --     file:close()
     67     -- end
     68     -- return testBMP
     69 end
     70 
     71 function BMP:createFHeader(biWidth,biHeight,biBitCount)
     72     self.bfType = 0x4D42
     73     self.bfSize = biWidth * biHeight * biBitCount/8 + 54     --写死54字节的header
     74     self.bfReserved1 = 0
     75     self.bfReserved2 = 0
     76     self.bfOffBits = 54                 -- 32位位图不要调色板,所以偏移54位后就是图像数据
     77     self.bfpackfmt = "<I2I4I2I2I4"
     78     print(string.format("文件大小为: %d ,文件头大小为: %d ",self.bfSize,string.packsize(self.bfpackfmt)))
     79     self.fheader = string.pack(self.bfpackfmt,self.bfType,self.bfSize,self.bfReserved1,self.bfReserved2,self.bfOffBits)
     80 end
     81 
     82 
     83 function BMP:createIHeader(biWidth,biHeight,biBitCount)
     84     self.biSize = 40                    -- infoheader头默认大小
     85     self.biWidth = biWidth
     86     self.biHeight = biHeight
     87     self.biPlanes = 1
     88     self.biBitCount = biBitCount
     89     self.bitCompression = 0
     90     self.biSizeImage = 0
     91     self.biXPelsPerMeter = 0
     92     self.biYPelsPerMeter = 0
     93     self.biClrUsed = 0
     94     self.biClrImortant = 0
     95     self.bipackfmt = "<I4I4i4I2I2I4I4I4I4I4I4"
     96     print(string.format("位图头大小为: %d ",string.packsize(self.bipackfmt)))   
     97     self.iheader = string.pack(self.bipackfmt,self.biSize,self.biWidth,self.biHeight,self.biPlanes,self.biBitCount,self.bitCompression,self.biSizeImage,self.biXPelsPerMeter,self.biYPelsPerMeter,self.biClrUsed,self.biClrImortant)
     98 end
     99 
    100 function BMP:creatRandomData()
    101     local singlefmt  = "<I1I1I1"
    102     local tab_plex = {}
    103     math.randomseed(os.time())
    104     local b,g,r  = math.random(256)-1,math.random(256)-1,math.random(256)-1
    105     local randomspeed = 12800
    106     for i = 1, self.biWidth*self.biHeight,1 do
    107         if i%randomspeed == 0 then 
    108             b,g,r  = math.random(256)-1,math.random(256)-1,math.random(256)-1
    109         end
    110         table.insert(tab_plex,string.pack(singlefmt,b,g,r))
    111     end
    112     self.data = table.concat(tab_plex)
    113 end
    114 
    115 function BMP:creatSingleData (b,g,r)
    116     local b = tonumber(b) or 0
    117     local g = tonumber(g) or 255
    118     local r = tonumber(r) or 0
    119     local singlefmt  = "<I1I1I1"
    120     local tab_plex = {}
    121     for i = 1, self.biWidth* self.biHeight,1 do
    122          table.insert(tab_plex,string.pack(singlefmt,b,g,r))
    123     end
    124     self.data = table.concat(tab_plex)
    125 end
    126 
    127 function BMP:creatFuncData (tab_arg)
    128 
    129 end
    130 
    131 function BMP:creatRandomMap(diffcult)
    132     -- 一个点具有实际表示 4*4的像素
    133     local plex_per_cell = 8
    134     local clr_open = {255,255,255}
    135     local clr_close = {0,0,0}
    136     -- 要生成的是64*64的0/1矩阵,如果false就是堵住的点,如果是true是开服的点
    137     local row,column = self.biWidth/plex_per_cell,self.biHeight/plex_per_cell
    138     local map = {}
    139     local singlefmt  = "<I1I1I1"
    140     local tab_plex = {}
    141     local diffcult = diffcult or 5
    142     math.randomseed(os.time())
    143     for i = 1,row do 
    144         for j =1,column do 
    145             local var = math.random(10) 
    146             if var>diffcult then
    147                 map[row*(i-1)+j] = true
    148             else
    149                 map[row*(i-1)+j] = false
    150             end
    151         end
    152     end
    153     print()
    154     -- 开始生成self.data 表,通过map表坐标映射生成self.data
    155     for i,isopen in ipairs(map) do
    156         local map_column = i%(column)
    157         if map_column ==0 then map_column = column end
    158         local map_row = (i - map_column)//row +1
    159         --print(map_row,map_column)
    160         --  map_row,map_column  都乘以4映射一个数组出来,再根据数据算出在self.data中的索引
    161         local map_t ={}
    162         for k = (map_row-1)*plex_per_cell,map_row*plex_per_cell do
    163             for j = (map_column-1)*plex_per_cell,map_column*plex_per_cell do 
    164              --   print(map_row,map_column, "=> ",k,j )
    165                 table.insert(map_t,{k,j})
    166             end
    167         end
    168 
    169         for _,pos in ipairs(map_t) do
    170             local k,j = table.unpack(pos)
    171             --print(k,j)
    172             if isopen then
    173                 tab_plex[(k-1)*self.biWidth + j] = string.pack(singlefmt,clr_open[1],clr_open[2],clr_open[3])
    174             else
    175                 tab_plex[(k-1)*self.biWidth + j] = string.pack(singlefmt,clr_close[1],clr_close[2],clr_close[3])
    176             end
    177         end
    178     end
    179     self.data = table.concat(tab_plex)
    180 end
    181 
    182 
    183 BMP:new("123")
    最后一个是按照块大小生成数组,再通过数组的值映射成图像的块,最后会生成这样的图片:
    Lua生成位图—string.pack打包数据的应用 - Fallever - 遂古之初
  • 相关阅读:
    MindSpore 建立神经网络
    MindSpore 数据加载及处理
    MindSpore 初探, 使用LeNet训练minist数据集
    Ubuntu 20.04 Xrdp Black Screen Ubuntu 20.04 Xrdp 远程桌面黑屏
    基于Transformer的ViT、DETR、Deformable DETR原理详解
    Ubuntu 18.04 / 20.04 自定义锁屏时间
    Transformer中K 、Q、V的设置以及为什么不能使用同一个值
    Auto-Encoding Scene Graphs for Image Captioning
    Eureka中读写锁的奇思妙想,学废了吗?
    PostgreSQL-查询所有索引
  • 原文地址:https://www.cnblogs.com/Fallever/p/6817275.html
Copyright © 2011-2022 走看看