bmp宽高比问题

2024-02-24

我一直在尝试了解 bmp 文件的工作原理,以便我可以渲染一些 Mandelbrot 设置图片并将它们输出为 bmp 文件,因为这似乎是最简单的方法之一,但由于某种原因,当我使用不是 1 的纵横比时:1 尽管它是 4 的幂(所以不需要填充)我得到像这样的奇怪的工件200:100 https://i.stack.imgur.com/L4EBO.png 48:100 https://i.stack.imgur.com/bfe2y.png我想做的是将偶数为白色、奇数为黑色的像素数组转换为 bmp,这个 (100:100) https://i.stack.imgur.com/L3FOv.png就是长宽比为 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))

好的,这是 BMP 版本。我把东西放在一个模块中,这样可能更容易使用。

local writeBMP = {}

local floor = math.floor
local insert, concat = table.insert, table.concat
local sub, char, rep = string.sub, string.char, string.rep

local 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

local function nextMul4(x)
    if ( x % 4 == 0 ) then
        return x
    else
        return x+4-(x%4)
    end
end

local function clamp(x)
    local y = x
    if ( x > 255 ) then
        y = 255
    elseif ( x < 0 ) then
        y = 0
    end
    return floor(y)
end

-- Accepts array of type pixelsXYC[X][Y][C] of numbers 0-255
-- C=1,2,3 are the red, green and blue channels respectively
-- X increases left to right, and Y increases top to bottom
function writeBMP.data(pixelsXYC, resolutionX, resolutionY)
    local Pixels = pixelsXYC
    local ResolutionX = resolutionX
    local ResolutionY = resolutionY
    assert(#Pixels == ResolutionX, "Table size and X resolution mismatch")
    assert(#Pixels[1] == ResolutionY, "Table size and Y resolution mismatch")

    local FileSize = Basen(ResolutionY*nextMul4(3*ResolutionX) + 54,2)
    local FileSize4 = tonumber(sub(FileSize,1,8),2) or 0
    local FileSize3 = tonumber(sub(FileSize,9,16),2) or 0
    local FileSize2 = tonumber(sub(FileSize,17,24),2) or 0
    local FileSize1 = tonumber(sub(FileSize,25,32),2) or 0

    local Width = Basen(ResolutionX,2)
    local Width4 = tonumber(sub(Width,1,8),2) or 0
    local Width3 = tonumber(sub(Width,9,16),2) or 0
    local Width2 = tonumber(sub(Width,17,24),2) or 0
    local Width1 = tonumber(sub(Width,25,32),2) or 0

    local Height = Basen(ResolutionY,2)
    local Height4 = tonumber(sub(Height,1,8),2) or 0
    local Height3 = tonumber(sub(Height,9,16),2) or 0
    local Height2 = tonumber(sub(Height,17,24),2) or 0
    local Height1 = tonumber(sub(Height,25,32),2) or 0

    local BMPSize = Basen(ResolutionY*nextMul4(3*ResolutionX),2)
    local BMPSize4 = tonumber(sub(BMPSize,1,8),2) or 0
    local BMPSize3 = tonumber(sub(BMPSize,9,16),2) or 0
    local BMPSize2 = tonumber(sub(BMPSize,17,24),2) or 0
    local BMPSize1 = tonumber(sub(BMPSize,25,32),2) or 0

    local Result = {}
    Result[1] = "BM" .. char(                   --File type 
        FileSize1,FileSize2,FileSize3,FileSize4,--File size
        0,0,                                    --Reserved
        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,0,                                   --Bit depth
        0,0,0,0,                                --Compression
        BMPSize1,BMPSize2,BMPSize3,BMPSize4,    --The amount of bytes pixel data will consume
        37,22,0,0,                              --Pixels per meter horizontal
        37,22,0,0,                              --Pixels per meter vertical
        0,0,0,0,                                --Number of colors in palatte
        0,0,0,0
    )

    local Y = ResolutionY
    while( Y >= 1 ) do
        for X = 1, ResolutionX do
            local r = clamp( Pixels[X][Y][1] )
            local g = clamp( Pixels[X][Y][2] )
            local b = clamp( Pixels[X][Y][3] )
            Result[#Result+1] = char(b)
            Result[#Result+1] = char(g)
            Result[#Result+1] = char(r)
        end
        -- byte alignment
        if ( ( (3*ResolutionX) % 4 ) ~= 0 ) then
            local Padding = 4 - ((3*ResolutionX) % 4)
            Result[#Result+1] = rep(char(0),Padding)
        end
        Y = Y - 1
    end

    return table.concat(Result)
end

function writeBMP.write(pixelsXYC, resolutionX, resolutionY, filename)
    local file = io.open(filename,"wb")
    local data = writeBMP.data(pixelsXYC, resolutionX, resolutionY)
    file:write(data)
end

return writeBMP

一个简单的测试:

-- writeBMP example
local writeBMP = require "writeBMP"

local resolutionX = 100
local resolutionY = 100
-- Pixel data
local pixels = {}
for x=1,resolutionX do
    pixels[x] = {}
    for y=1, resolutionY do
        pixels[x][y] = {}
        local red = 255*(resolutionX-x+resolutionY-y)/(resolutionX+resolutionY)
        local green = 255*y/resolutionY
        local blue = 255*x/resolutionX
        pixels[x][y][1] = red
        pixels[x][y][2] = green
        pixels[x][y][3] = blue
    end
end

writeBMP.write(pixels,resolutionX,resolutionY,"testwritebmp.bmp")
return

Note:在 BMP 中,Y 轴从底部开始。我更习惯于计算机图形学中从上到下的Y轴(所以我就是这样写的)。

感谢 HAX 提供的代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

bmp宽高比问题 的相关文章

  • 使用 corona sdk 验证电子邮件地址

    在我的项目中 有一个供用户填写详细信息的表单 其中有一个文本字段用于输入用户的电子邮件 ID 所以我需要在 corona 项目中验证该文本字段中的电子邮件 试试这个正则表达式 local email email protected cdn
  • lua http套接字超时

    LuaSocket HTTP 模块文档说可以在 HTTP 连接上设置超时 可以设置以下常量来控制 HTTP 模块的默认行为 PORT 用于连接的默认端口 PROXY 用于连接的默认代理 TIMEOUT 设置所有I O操作的超时时间 USER
  • 如何在 Lua 中实现 OO?

    Lua 没有内置对 OO 的支持 但它允许您自己构建它 您能否分享一些实现面向对象的方法 请为每个答案写一个例子 如果您有更多示例 请发布另一个答案 我喜欢将 OOP 视为容器 对象 内的数据封装以及可以使用该数据完成的操作子集 还有很多内
  • 如何在Conky中实现一个基本的Lua功能?

    我正在尝试向我的 Conky 添加一个函数 该函数打印字符串的长度以用于调试目的 代码位于名为的文件内test lua 非常简单 function test word return string len word end 我这样加载它 在我
  • 尝试将 nil 与数字堆栈回溯进行比较?

    我正在通过以下链接玩 Lua https www lua org pil 4 2 html https www lua org pil 4 2 html并对某一点感到困惑 Lua 5 2 4 Copyright C 1994 2015 Lu
  • 为什么 LuaJIT 这么好?

    编辑 不幸的是 LuaJIT 已从下面链接的比较中删除 This 比较 http shootout alioth debian org u64 which programming languages are fastest php编程语言的
  • 去掉尾随零和小数点

    使用 Lua 我将数字格式化为可变位数并去掉尾随零 小数点 例如 string format precision f value gsub 0 1 gsub 值的类型为数字 正数 负数 整数 小数 所以任务已经解决了 但出于美学 教育和性能
  • Lua中按字符分割字符串

    我有像这样的字符串 ABC DEF 我需要将它们分开 字符并将两个部分分别分配给一个变量 在 Ruby 中 我会这样做 a b ABC DEF split 显然Lua没有这么简单的方法 经过一番挖掘后 我找不到一种简短的方法来实现我所追求的
  • 使用 ZPL 打印 BMP

    如何使用 ZPL II 打印位图 BMP 图像 我使用 DY 将 BMP 下载到打印机 DYR PRINT B B
  • 如何在我的 Lua 脚本中添加“睡眠”或“等待”?

    我正在尝试通过更改一天中的时间来为游戏制作一个简单的脚本 但我想快速完成 这就是我要说的 function disco hour minute setTime 1 0 SLEEP setTime 2 0 SLEEP setTime 3 0
  • 如何通过 C API 在自己的环境中执行不受信任的 Lua 文件

    我想通过调用在其自己的环境中执行不受信任的 lua 文件lua setfenv http pgl yoyo org luai i lua setfenv这样它就不会影响我的任何代码 该函数的文档仅解释了如何调用函数 而不解释如何执行文件 目
  • 关闭 Löve2D 中的抗锯齿功能

    我在用着L ve2D http love2d org用于编写一个小游戏 L ve2D 是 Lua 的开源游戏引擎 我遇到的问题是 当您在非整数位置绘制精灵时 某些抗锯齿过滤器会自动应用于精灵 love graphics draw sprit
  • 推送 Lua 表

    我已经创建了一个Lua表C 但我不知道如何将该表推入堆栈顶部 以便我可以将其传递给 Lua 函数 有谁知道如何做到这一点 这是我当前的代码 lua createtable state libraries size 0 int table i
  • Lua 上的 For 循环

    我的作业是如何执行 for 循环 我已经从数字上弄清楚了 但无法从名称上弄清楚 我想创建一个 for 循环来运行名称列表 以下是我到目前为止所拥有的 names John Joe Steve for names 1 3 do print n
  • lua 和 walk_block 中的 pandoc 过滤器

    我正在尝试应用一个 LUA 过滤器 该过滤器只会更改文档的正文 而不影响元数据 而且比我想象的要难 过滤器应将文本添加到内联元素和块元素的前面和后面 如果它适用于内联元素 这里Code 对于块元素失败CodeBlock function P
  • 在Windows上使用gcc 5.3.0编译Lua 5.2.4模块

    我需要用 gcc 5 3 0 编译 Lua 5 2 4 模块 在 Windows 上 在此之前 我按照以下步骤构建 Lua 5 2 4 gcc c DLUA BUILD AS DLL c ren lua o lua obj ren luac
  • Lua 中的贪婪/非贪婪模式匹配和可选后缀

    在 Lua 中 我正在尝试模式匹配和捕获 384 Critical Strike Reforged from Parry Chance as 384 Critical Strike 后缀在哪里 Reforged from s 是可选的 长版
  • 如何从 Lua 字符串中删除所有特殊字符、标点符号和空格?

    在Lua中 我只能找到其他语言的示例 如何从字符串中删除所有标点符号 特殊字符和空格 所以 举例来说 s t r i p p e d会成为stripped In Lua 模式 https www lua org manual 5 3 man
  • 如何将 Lua 粘合到 C++ 代码?

    您使用 Luabind toLua 或其他库 如果使用 是哪一个 还是根本不使用 每种方法都有哪些优点和缺点 我不太同意 自己投票 将基本类型和静态 C 函数绑定到 Lua 是微不足道的 是的 但是当你开始处理表和元表时 情况就会发生变化
  • 如何编写可以与操作系统交互的VLC插件

    我需要找出是否有可能以及如何 我不关心C C Lua Python 制作一个VLC插件 其目的是由VLC播放器在特定时间调用视频流的将执行一些操作 我需要做的操作是打开 UDP 套接字并发送从当前播放的视频附带的文件中读取的一些数据 我需要

随机推荐

  • Maven 过滤

    我正在使用 Maven 3 x 在 Hudson 中构建 Android 应用程序 作为构建的一部分 我使用过滤 配置文件对 strings xml 文件进行文本替换 因此 在 strings xml 中 我将包含以下条目
  • 3D 绘图中 y 轴和 z 轴的交换位置

    默认情况下 在 3D 中绘制一组点 或其他内容 matplotlib 找到z垂直轴 如下所示 代码如下 我需要交换z and y轴 使得y轴垂直显示 我环顾四周但找不到办法告诉matplotlib去做这个 Add 我不想诉诸于交换数据和标签
  • 好友列表:关系数据库表设计

    所以 好友列表的现代概念是 假设我们有一个名为 Person 的表 现在 该 Person 需要有许多好友 其中每个好友也属于 person 类 构建关系最明显的方法是通过连接表 IE buddyID person1 id person2
  • Shiny布局,是否可以在Shiny中拥有左侧和骑侧边栏布局?

    在 Shiny 中可以有这样的布局吗 我理想地想要一个左侧和右侧边栏 我已经看到了一些解决方案shinydashboardPlus但这不正是我所追求的 我有一个与此示例结构类似的应用程序 mychoices lt c pick me A p
  • 如何在此处的集群地图中显示重复的制造商

    我在这里使用地图并使用聚类 但我在显示坐标相同 dublicate 的制造商时遇到问题 当我放大聚类时 不幸的是 制造商不可见 但聚类仍然可见 当集群缩放时如何显示这些标记 我的集群选项如下 var clusteredDataProvide
  • 使用 Rails5 和 ActionCable 时不允许请求来源:http://localhost:3001

    Rails 5 0 0 beta2 中尝试使用 ActionCable 的应用程序出现服务器问题 使用 localhost 3000 效果很好 因为这是大多数 ActionCable 的默认设置 但是如果我尝试在端口 3001 上运行 Ra
  • 有没有办法在 Azure DevOps 中创建组织仪表板?

    我们的团队目前正在使用 DevOps 并对一切的运行情况感到非常满意 我们在每个项目中设置了仪表板来跟踪工作项和冲刺 并希望在组织级别执行相同的操作 有没有办法创建组织中多个项目的总体概述 不幸的是 我们无法创建组织级别的仪表板 它不受支持
  • 将颜色从 Javascript 传递到片段着色器

    我目前正在学习webgl 有一个问题 我正在尝试制作一个三角形并将颜色信息从 js 文件传递 到片段着色器中 以下是我的js代码 var VSHADER SOURCE attribute vec4 a Position n attribut
  • Python - 通常如何使用递归方法将实例变量作为隐式参数传递给方法

    我在将对象的实例变量传递给实例方法时遇到问题 我在其他地方搜索过这个 但我一直找到的只是有关如何使用对象将对象传递给方法的信息self 我已经知道了 或者只是关于类和实例方法之间的一般差异的教程 但没有具体回答我的问题 我的问题的答案肯定存
  • CMake graphviz 自动生成

    我知道通过 CLI 生成 CMake 项目依赖关系图的常用方法 cmake graphviz file 但是有没有一种方法可以通过在 CMakeList 中设置标志或命令来自动生成它 这个想法是让 CMakeLists txt 本身触发图形
  • PHP递归函数返回值[重复]

    这个问题在这里已经有答案了 我在 PHP 中编写了一个递归函数来裁剪文本 裁剪后的文本将 附加到末尾 未裁剪的文本将以其原始状态返回 如果文本适合最大宽度 则该方法有效 但是 如果它不适合给定的宽度 该函数将不会返回值 但它应该返回 看来整
  • 更改默认拨号器的请求在某些设备上不显示系统对话框

    我们的应用程序需要成为默认拨号器应用程序 也称为 默认电话处理程序 默认呼叫应用程序 以便它能够在 Android 下拨打电话新的权限策略 https support google com googleplay android develo
  • 使用 Spring Hibernate 使用注释编写更少的 DAO

    我的 Spring Hibernate 配置文件很小而且非常紧凑 我使用自动扫描来查找我的模型实体 DAOS 我不想为层次结构中的每个实体编写 DAO DAOImpl 有些可能有资格拥有自己的 例如 如果他们与其他实体有复杂的关系并且需要的
  • ruby中使用数组进行数据库查询

    我正在尝试查找数组中具有值的所有行 这是我的代码 require sqlite3 db SQLite3 Database new test sqlite res db query SELECT w1 synsetid FROM words
  • 左、中、右对齐同一行底部的 div

    我想在同一行显示三个 div 这三个都有不同的宽度和高度 并且它们不是直文本 我想左对齐一个 一直到左边 右对齐另一个 一直到右边 然后将第三个居中 在包含 div 的中间 在本例中是整个页面 此外 我希望这三个 div 与包含的 div
  • 修复错误mysql服务器已经消失[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我的 VPS 经常出现故障 MySQL 服务器已消失 错误 2006 并失去连接 我增加了 my cnf 中变量的值 但情况没有改善 这是我的 cnf
  • 静默 /dev/tcp/host/port 重定向错误

    以下脚本将测试从 8079 到 8081 的 tcp 端口是否打开或关闭 for port in 8079 8081 do echo gt dev tcp 127 0 0 1 port echo port port is open echo
  • 对齐双轴刻度时出现问题

    我创建了一个有 2 个 y 轴的 matplotlib 图 y 轴有不同的比例 但我希望刻度线和网格对齐 我从 Excel 文件中提取数据 因此无法事先知道最大限制 creates double y axis ax2 ax1 twinx l
  • .netcore 应用程序 wwwroot 之外的静态文件

    我在用着https github com ebekker ACMESharp https github com ebekker ACMESharp在我的 home 网络服务器上使用 SSL 它是免费的 O 这是相当手动的 但注意到在维基上它
  • bmp宽高比问题

    我一直在尝试了解 bmp 文件的工作原理 以便我可以渲染一些 Mandelbrot 设置图片并将它们输出为 bmp 文件 因为这似乎是最简单的方法之一 但由于某种原因 当我使用不是 1 的纵横比时 1 尽管它是 4 的幂 所以不需要填充 我