Lua - xterm 256 色渐变脚本
这让我有些困扰,而且我不确定是否有答案。我知道有一些模块,比如 Love2D 可以实现渐变,我猜它使用 RGB 颜色。然而,我需要找到一些相似的东西使用 xterm 256 色,但我似乎找不到任何渐变映射来辅助处理。
我猜我将不得不创建一个“最接近 RGB 颜色”的颜色,并从中创建一个渐变,将相应的 RBG 匹配到最接近的 xterm 匹配,但说实话,我甚至不知道从哪里开始。我知道 Python 中有一个“将 xterm 转换为 RGB hex”的脚本(位于 这里),但我不知道如何将其转换为 Lua。
最终,我想做的就是能够将文本变成彩虹渐变色。我目前有一个函数来返回 xterm 颜色,但它完全是随机的,而且输出可能有点难以阅读。这是我用的代码。@x 代表转换为 xterm 颜色,后面是一个三位数字码(001 到 255),然后是文本。
function rainbow(text)
local rtext = ""
local xcolor = 1
local sbyte = 1
for i = 1, #text do
math.randomseed(os.time() * xcolor * sbyte)
sbyte = string.byte(i)
xcolor = math.random(1, 255)
rtext = rtext .. "@x" .. string.rep("0", 3 - string.len(xcolor)) .. xcolor .. text:sub(i,i)
end
return rtext
end
例如,print(rainbow("测试")) 将导致:
@x211T@x069e@x154s@x177t
显然,这不是渐变,也不是我想要的结果。我想要的是否可能实现,还是一个无望的事情?
编辑
我知道 256 中颜色的限制,也知道没有太多的余地。正如评论中指出的那样,会有很多相同颜色的匹配,所以我会得到一串相同颜色的字符串。实际上,这对我没有关系。无论它做出了多少实际的转换,我希望它可以尽可能地模拟渐变。
如果我能够正确地创建颜色组,而不必轮询图表,那就太好了。我可能需要做的是创建一个“兼容颜色方案”表来处理,除非有人有更好的想法。
我用 ANSI 256 色转义代码模式完成了这个。
-- 参考 ANSI 256 色 = https://robotmoon.com/256-colors/ str = '\27[38;5;34mG\27[38;5;35mr\27[38;5;36ma\27[38;5;37md\27[38;5;38mi\27[38;5;39me\27[38;5;50mn\27[38;5;51mt\27'
if f then f.Destroy() end
f=createForm()
pb=createPaintBox(f)
pb.Canvas.Font.Size=52
pb.Align='alClient'
local rect={}
rect.Left=0
rect.Top=0
rect.Right=pb.Width
rect.Bottom=pb.Height
pb.Repaint()
pb.Canvas.Font.Style='fsBold'
pb.Canvas.Font.Name='Trebuchet MS'
pb.Canvas.Font.Color = 0
pb.Canvas.textRect(rect,16,54,'Gradient')
pb.Canvas.textRect(rect,12,50,str)
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法

定义
nearest_term256_color_index函数:local abs, min, max, floor = math.abs, math.min, math.max, math.floor local levels = {[0] = 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff} local function index_0_5(value) -- value = color component 0..255 return floor(max((value - 35) / 40, value / 58)) end local function nearest_16_231(r, g, b) -- r, g, b = 0..255 -- returns color_index_from_16_to_231, appr_r, appr_g, appr_b r, g, b = index_0_5(r), index_0_5(g), index_0_5(b) return 16 + 36 * r + 6 * g + b, levels[r], levels[g], levels[b] end local function nearest_232_255(r, g, b) -- r, g, b = 0..255 local gray = (3 * r + 10 * g + b) / 14 -- this is a rational approximation for well-known formula -- gray = 0.2126 * r + 0.7152 * g + 0.0722 * b local index = min(23, max(0, floor((gray - 3) / 10))) gray = 8 + index * 10 return 232 + index, gray, gray, gray end local function color_distance(r1, g1, b1, r2, g2, b2) return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2) end local function nearest_term256_color_index(r, g, b) -- r, g, b = 0..255 local idx1, r1, g1, b1 = nearest_16_231(r, g, b) local idx2, r2, g2, b2 = nearest_232_255(r, g, b) local dist1 = color_distance(r, g, b, r1, g1, b1) local dist2 = color_distance(r, g, b, r2, g2, b2) return dist1 < dist2 and idx1 or idx2 end定义
generate_gradient函数,该函数将@x...插入您的文本:local unpack, tonumber = table.unpack or unpack, tonumber local function convert_color_to_table(rrggbb) if type(rrggbb) == "string" then local r, g, b = rrggbb:match"(%x%x)(%x%x)(%x%x)" return {tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)} else return rrggbb end end local function round(x) return floor(x + 0.5) end local function generate_gradient(text, first_color, last_color) local r, g, b = unpack(convert_color_to_table(first_color)) local dr, dg, db = unpack(convert_color_to_table(last_color)) local char_pattern = "[^\128-\191][\128-\191]*" local n = max(1, select(2, text:gsub(char_pattern, "")) - 1) dr, dg, db = (dr - r)/n, (dg - g)/n, (db - b)/n local result = "" for c in text:gmatch(char_pattern) do result = result..("@x%03d"):format(nearest_term256_color_index( round(r), round(g), round(b)))..c r, g, b = r + dr, g + dg, b + db end return result end在终端中测试:
local function print_with_colors(str) print( str:gsub("@x(%d%d%d)", function(color_idx) return "\27[38;5;"..color_idx.."m" end) .."\27[0m" ) end local str = "Gradient" local blue, red = {0, 0, 255}, "#FF0000" str = generate_gradient(str, blue, red) -- gradient from blue to red print(str) print_with_colors(str)rainbow()不是渐变色,它应该是一系列渐变色的链。