【发布时间】:2021-07-01 15:53:28
【问题描述】:
我一直在尝试了解 bmp 文件的工作原理,以便我可以渲染一些 Mandelbrot 集图片并将它们输出为 bmp 文件,因为这似乎是最简单的方法之一,但由于某种原因,当我使用't 1:1 即使它是 4 的幂(所以不需要填充) 我得到像这些 200:100 48:100 这样奇怪的伪影我想要做的是把一个像素数组变成白色偶数和奇数黑色成 bmp,this (100:100) 是 1:1 纵横比的样子。 我已经尝试通读维基百科文章,看看我是否能弄清楚我做错了什么,但我仍然不明白我错过了什么。
这是我目前用 Lua 编写的脚本:
ResolutionX = 100
ResolutionY = 100
local cos, atan, sin, atan2, sqrt, floor = math.cos, math.atan, math.sin, math.atan2, math.sqrt, math.floor
local insert, concat = table.insert, table.concat
local sub, char, rep = string.sub, string.char, string.rep
io.output("Test.bmp")
function Basen(n,b)
n = floor(n)
if not b or b == 10 then return tostring(n) end
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local t = {}
repeat
local d = (n % b) + 1
n = floor(n / b)
insert(t, 1, digits:sub(d,d))
until n == 0
return rep("0",32-#t)..concat(t,"")
end
FileSize = Basen(ResolutionY*ResolutionX*3 + 54,2)
FileSize4 = tonumber(sub(FileSize,1,8),2) or 0
FileSize3 = tonumber(sub(FileSize,9,16),2) or 0
FileSize2 = tonumber(sub(FileSize,17,24),2) or 0
FileSize1 = tonumber(sub(FileSize,25,32),2) or 0
Width = Basen(ResolutionX,2)
print("Width: ",Width)
Width4 = tonumber(sub(Width,1,8),2) or 0
Width3 = tonumber(sub(Width,9,16),2) or 0
Width2 = tonumber(sub(Width,17,24),2) or 0
Width1 = tonumber(sub(Width,25,32),2) or 0
Height = Basen(ResolutionY,2)
print("Height: ",Height)
Height4 = tonumber(sub(Height,1,8),2) or 0
Height3 = tonumber(sub(Height,9,16),2) or 0
Height2 = tonumber(sub(Height,17,24),2) or 0
Height1 = tonumber(sub(Height,25,32),2) or 0
BMPSize = Basen(ResolutionY*ResolutionX*3,2)
BMPSize4 = tonumber(sub(BMPSize,1,8),2) or 0
BMPSize3 = tonumber(sub(BMPSize,9,16),2) or 0
BMPSize2 = tonumber(sub(BMPSize,17,24),2) or 0
BMPSize1 = tonumber(sub(BMPSize,25,32),2) or 0
print("TotalSize: ",FileSize1,FileSize2,FileSize3,FileSize4,"\nWidth: ",Width1,Width2,Width3,Width4,"\nHeight: ",Height1,Height2,Height3,Height4,"\nImage data: ",BMPSize1,BMPSize2,BMPSize3,BMPSize4)
Result = {"BM"..char( --File type
FileSize1,FileSize2,FileSize3,FileSize4,--File size
0,0,0,0, --Reserved
54,0,0,0, --Where the pixel data starts
40,0,0,0, --DIB header
Width1,Width2,Width3,Width4, --Width
Height1,Height2,Height3,Height4, --Height
1,0, --Color planes
24,00, --Bit depth
0,0,0,0, --Compression
BMPSize1,BMPSize2,BMPSize3,BMPSize4, --The amount of bytes pixel data will consume
Width1,Width2,Width3,Width4,
Height1,Height2,Height3,Height4,
0,0,0,0, --Number of colors in palatte
0,0,0,0
)}
for X = 0, ResolutionX - 1 do
for Y = 0, ResolutionY - 1 do
insert(Result,rep(char(255 * ((X + 1) % 2) * ((Y + 1) % 2)),3))
end
end
io.write(table.concat(Result))
【问题讨论】:
-
for X = 0, ResolutionX - 1 do必须是内循环。 -
注意BMP中Y轴从底部开始(可以倒数),不是英文阅读顺序
-
我想我应该更加关注它现在工作的循环感谢@EgorSkriptunoff
-
@HAX 你也缺少字节对齐,每行的字节数应该是4的倍数。在这种情况下,如果宽度不是4的倍数,可能会出现问题.稍后我会发布更完整的答案。
-
@Real 我已经解决了,在我让循环正常工作后,我只是在循环之前添加了
Padding = 0 if (ResolutionX*3)%4 > 0 then Padding = 4 - (ResolutionX*3)%4 end,并在 X 循环之后添加了Output[#Output+1] = rep(char(0),Padding)。