Lua生成位图—string.pack打包数据的应用
Posted 遂古之初
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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打包数据的应用的主要内容,如果未能解决你的问题,请参考以下文章
lua 声明local socket = require"socket" 等代码运行成功后,怎么打包生成exe
将 Java 位图打包到 ByteBuffer 中 - 字节顺序与像素格式和字节序不匹配(ARM)