十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

WezTerm 配色 Lua API 详解:`color:linear_rgba()` 与线性 RGBA 色彩空间转换

WezTerm 配色 Lua API 详解:`color:linear_rgba()` 与线性 RGBA 色彩空间转换 WezTerm 配色 Lua API 详解color:linear_rgba()与线性 RGBA 色彩空间转换【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/weztermlinear_rgba()是 WezTerm 配色 Lua 模块wezterm.color提供的一个颜色转换方法它把当前颜色对象从 sRGB 编码转换为线性 RGBA 分量并以0.0-1.0范围的浮点数元组返回。本文以该 API 为核心讲解其用法、底层转换公式与源码实现并结合 WezTerm 中渐变、对比度计算等真实场景说明为什么需要在线性色彩空间中处理颜色。读完本文你将能够正确使用linear_rgba()及其配套方法并理解终端渲染管线中的颜色编码差异。一、方法签名与基本用法linear_rgba()是wezterm.color模块中颜色对象的方法通过wezterm.color.parse()详见 parse 方法文档构造颜色对象后调用 r, g, b, a wezterm.color.parse(purple):linear_rgba() print(r, g, b, a) 07:32:17.734 INFO logging lua: 0.2158605307340622 0 0.2158605307340622 1调用结果是一个包含四个元素的元组依次为红色、绿色、蓝色、透明度分量每个分量的取值区间为0.0-1.0对应 0% 到 100% 的强度分量是线性空间下的值详见下文第二节的转换公式透明度alpha分量在 sRGB 色彩空间中本身就是线性的因此不经过伽马校正原样返回。以上例中的purple为例它在 sRGB 编码下是#800080R128G0B128A255经过线性化后红色与蓝色分量变为约0.2159绿色保持0alpha 保持1。二、为什么需要线性 RGBAsRGB 与线性空间的区别终端配色中的大部分颜色值#RRGGBB、颜色名称、rgba()表达式等都以sRGB 编码存储。sRGB 是一种非线性的伽马编码为了适配早期 CRT 显示器对暗部敏感的特性sRGB 在亮部与暗部分别采用了不同的映射曲线因此 sRGB 通道值并不直接代表物理光强度。而线性空间linear RGBA中的每个通道值与光的强度成正比。二者的区别直接影响两类关键计算颜色插值如果直接在 sRGB 空间中对两个颜色做线性插值得到的中间色会在暗部区域出现明显偏暗、发灰的现象只有把颜色转换到线性空间后再插值插值结果才符合人眼的感知预期。亮度与对比度计算相对亮度relative luminance是对 RGB 通道加权求和得到的该公式只有在线性分量上计算才正确。WezTerm 的contrast_ratio()方法正是基于线性空间实现见下文第四节。三、源码实现线性化转换公式linear_rgba()的 Lua 绑定位于 lua-api-crates/color-funcs/src/lib.rs实现非常直接调用颜色对象内部的to_linear()方法并把得到的LinearRgba四个通道拆成 Lua 元组返回methods.add_method(linear_rgba, |_, this, _: ()| { let rgba this.0.to_linear(); Ok((rgba.0, rgba.1, rgba.2, rgba.3)) });真正完成转换的是 color-types/src/lib.rs 中SrgbaTuple::to_linear()pub fn to_linear(self) - LinearRgba { fn to_linear(v: f32) - f32 { if v 0.04045 { v / 12.92 } else { ((v 0.055) / 1.055).powf(2.4) } } // Note that alpha is always linear LinearRgba( to_linear(self.0), to_linear(self.1), to_linear(self.2), self.3, ) }该公式是 sRGB 标准的线性化定义分两段处理当通道值v 0.04045暗部时采用简单的线性缩放v / 12.92当v 0.04045亮部时采用指数映射((v 0.055) / 1.055)^2.4。值得注意的是alpha 通道不参与上述变换——源码注释明确指出“alpha is always linear”即透明度在任何色彩空间中都是线性量因此第四个返回值与原值一致。对于 8 位 sRGB 输入u8编码LinearRgba::with_srgba()color-types/src/lib.rs提供了同等的转换入口并利用预先计算好的 256 项查找表SRGB_TO_F32_TABLE见 color-types/src/lib.rs加速避免每次转换重复做浮点幂运算——这是终端渲染热路径中常见的工程优化手段。四、配套方法与逆向转换逆向转换回 sRGBlinear_rgba()是单向“导出”接口与之对应的逆向转换发生在LinearRgba::to_srgb()color-types/src/lib.rs中它把线性分量按 sRGB 标准重新编码。在 Lua 侧用户更常用的配套方法是color:srgba_u8()见 srgba_u8 方法文档它返回0-255整数范围的 sRGB RGBA 元组便于与配置文件中常见的 8 位颜色值对齐 r, g, b, a wezterm.color.parse(purple):srgba_u8() print(r, g, b, a)基于线性空间的对比度计算linear_rgba()返回的线性分量是 WezTerm 内部许多颜色运算的基础。例如color:contrast_ratio()见 contrast_ratio 方法文档在实现上先调用to_linear()再以相对亮度公式0.2126 * R 0.7152 * G 0.0722 * Bcolor-types/src/lib.rs计算两个颜色的对比度——该公式定义在 WCAG 规范中其前提正是分量处于线性空间。其他颜色通道表示同一颜色对象还提供hsla()HSL 色彩空间与laba()CIE Lab* 色彩空间等转换方法它们与linear_rgba()一起构成了 WezTerm 面向 Lua 脚本的完整颜色数学工具箱均在 lua-api-crates/color-funcs/src/lib.rs 中注册。五、典型应用场景场景一自定义渐变插值当你在 WezTerm 配置中实现自己的颜色渐变函数时应当把两个端点颜色先线性化、再插值、最后转回 sRGB。示例local wezterm require(wezterm) local function lerp(a, b, t) return a (b - a) * t end -- 在 sRGB 与线性空间之间互相转换 local function color_to_linear(c) local r, g, b, a c:linear_rgba() return { r, g, b, a } end local function linear_to_srgb(t) -- 使用 srgba_u8 或借助 wezterm.color 构造器转回 return wezterm.color.from_hsla(0, 0, 0, 1) -- 示意占位 end提示WezTerm 内置的wezterm.gradient与wezterm.color.gradient已经在内部完成线性空间的插值处理可直接使用。场景二主题配色的一致性校验linear_rgba()常用于在 Lua 脚本中统一颜色的内部表示。无论配色来自颜色名称、十六进制还是rgba()字符串先调用一次linear_rgba()即可获得可比较的线性分量配合contrast_ratio()可以编写“前景/背景对比度自动校验”之类的配置辅助脚本。六、注意事项linear_rgba()自 2022-08-07 版本构建标识20220807-113146-c2fee766起可用使用前请确认 WezTerm 版本不低于该构建返回值是浮点元组不适用于直接写回配置项——配置项通常接受 sRGB 字符串如需 8 位整数形式请使用srgba_u8()alpha 分量不做伽马校正透明度的线性属性因此不要对 a 值套用线性化公式若你希望把线性 RGBA 重新编码回 sRGB 浮点形式可参考源码中LinearRgba::to_srgb()的实现其暗部与亮部分别使用线性缩放与1.055 * v^(1/2.4) - 0.055的逆变换。七、参考实现索引Lua 绑定与模块注册lua-api-crates/color-funcs/src/lib.rssRGB 与线性空间转换公式color-types/src/lib.rs线性 RGBA 数据结构与查找表优化color-types/src/lib.rs对比度计算依赖线性分量color-types/src/lib.rs配套方法文档srgba_u8、contrast_ratio、parse【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表