仓颉三方库实战教程:用 color4cj 处理颜色 [特殊字符]
本文是一篇面向仓颉(Cangjie)开发者的实战教程,手把手教你在项目中集成与使用 color4cj 库,完成颜色字符串解析、标准化、跨空间转换与插值等常见需求,并结合数值诊断与性能建议,帮助你快速落地。
提示:本文示例以 color4cj v0.0.2 与 Cangjie v1.0.3+ 为参考,若你的版本不同,API 行为可能略有差异,请以项目 README.md 与 doc/feature_api.md 为准。
1. 为什么选 color4cj?
- 覆盖广:原生支持 30+ 常见与专业色彩空间的双向转换。
- 易集成:统一 convert 路由与 toRgb/fromRgb 入口,降低 API 学习成本。
- 开箱即用:解析与标准化支持 CSS3/4 语法与命名颜色,简单字符串即可运行。
- 结果友好:提供 RGBA 数值与字符串化工具,易于与前端/UI 渲染衔接。
2. 获取与引入
你可以通过两种方式将 color4cj 引入到你的项目中:
方式 A:本地路径依赖(适合同仓或本地开发)
# cjpm.toml(示例)
[dependencies]
color4cj = { path = "../color4cj" }
方式 B:Git 依赖(适合跨仓复用)
# cjpm.toml(示例)
[dependencies]
color4cj = { git = "https://gitcode.com/cj-awaresome/color4cj.git", tag = "v0.0.2" }
注意:依赖写法可能随 cjpm 版本演进,请以你当前的 cjpm 文档为准。若暂无注册仓库,你也可以直接复制需要的模块或使用子模块管理。
3. 快速上手(Hello Color)
示例:解析/标准化/字符串化,再做空间转换与插值。
package tutorial.color4cj.hello
import color4cj.parse.parseColorToRgb
import color4cj.parse.parseAlpha
import color4cj.normalize.normalize
import color4cj.normalize.normalizeString
import color4cj.rgba.rgba
import color4cj.rgba.rgbaString
import color4cj.space.convert
import color4cj.interpolate.interpolateAt
import color4cj.interpolate.interpolateStringSpace
main() {
// 解析命名颜色
match (parseColorToRgb("CornflowerBlue")) {
case Some(rgb) => println("name => [${rgb[0]}, ${rgb[1]}, ${rgb[2]}], a=${parseAlpha("CornflowerBlue")}\n")
case None => println("parse name failed\n")
}
// 标准化到数组(RGBA Float64)
match (normalize("rgba(255,0,0,50%)", "array")) {
case Some(v) => println("normalize array => [${v[0]}, ${v[1]}, ${v[2]}], a=${v[3]}\n")
case None => println("normalize array failed\n")
}
// 字符串化(保持输入风格或转为 rgba(...))
match (normalizeString("CornflowerBlue")) {
case Some(s) => println("normalizeString => ${s}\n")
case None => println("normalizeString failed\n")
}
// 空间转换:RGB -> OKLab
match (convert("rgb", "oklab", [255.0, 0.0, 0.0])) {
case Some(oklab) => println("rgb→oklab => [${oklab[0]}, ${oklab[1]}, ${oklab[2]}]\n")
case None => println("convert rgb→oklab failed\n")
}
// 插值:在 RGB 与 OKLab 中对比效果
let palette: Array<String> = ["red", "rgba(0,0,255,0.5)", "#00ff00"]
match (interpolateAt(palette, 0.25)) {
case Some(rgbaF) => println("RGB interpolate t=0.25 => [${rgbaF[0]}, ${rgbaF[1]}, ${rgbaF[2]}], a=${rgbaF[3]}\n")
case None => println("RGB interpolate failed\n")
}
match (interpolateStringSpace(palette, 0.5, "oklab")) {
case Some(s) => println("OKLab interpolate t=0.5 => ${s}\n")
case None => println("OKLab interpolate failed\n")
}
}
构建与运行:
cjpm update
cjpm build
cjpm run
测试用例执行:
cjpm test

4. 统一路由与范围约定(必读)
- convert(spaceFrom, spaceTo, values):适用于多数空间间的转换;空间字符串不区分大小写。
- toRgb/fromRgb:RGB 专用入口,约定 RGB 使用 0…255 范围。
- 线性/近线性空间(XYZ/LMS/UCS/UVW/Lab/Luv/OKLab 等)通常使用 0…100 范围;角度单位为度。
- 返回值均为 Option(?T):转换失败或不可达时返回 None,请在 match 中处理。
5. 插值策略如何选?
- RGB:直觉友好、实现简单,但可能在高饱和过渡中产生非感知均匀的路径。
- Lab/Luv:历史经典方案,相较 RGB 更接近感知均匀,但不同显示与白点假设下表现差异。
- OKLab:近年较受欢迎的感知空间之一,插值路径更自然;在高饱和复合原色(如黄)往返时可能存在少量残差(见第 7 章)。
建议:对 UI/可视化渐变,优先尝试 OKLab 或 Lab;对兼容性与性能要求高的场景,可在 RGB 插值后做一次到目标空间的映射。
6. 字符串化与命名颜色
- rgba(cstr): 将字符串解析为 RGBA(Float64),alpha 范围 0…1。
- rgbaString/rgbaStringFixed: 产出 rgb()/rgba() 字符串,便于拼接到前端样式或导出。
- getColorRgb(name): 大小写不敏感查询命名颜色,支持 X11/HTML/NTC/Pantone/Roygbiv/Basic。
7. 数值诊断:OKLab 往返残差与排查
在高饱和复合原色(尤其是黄)上,OKLab 的往返可能出现少量残差。这源于近似数值例程(cbrt/幂/gamma)的累计误差与常量精度限制。本库在测试中将往返断言容差调整到 25.0 以保证可逆性与工程可用性。
你可以在自己的项目里增加一个小工具,帮助定位与量化残差:
package tutorial.color4cj.diag
import color4cj.space.rgbToOklab
import color4cj.space.oklabToRgb
public func diagRoundtripRgbOklab(label: String, rgb: Array<Float64>): Void {
match (rgbToOklab(rgb)) {
case Some(oklab) => {
match (oklabToRgb(oklab)) {
case Some(rgb2) => {
let dx = rgb2[0] - rgb[0]
let dy = rgb2[1] - rgb[1]
let dz = rgb2[2] - rgb[2]
println("[${label}] rgb=[${rgb[0]},${rgb[1]},${rgb[2]}] -> rgb2=[${rgb2[0]},${rgb2[1]},${rgb2[2]}], residual=[${dx},${dy},${dz}]\n")
}
case None => println("oklabToRgb failed\n")
}
}
case None => println("rgbToOklab failed\n")
}
}
main() {
diagRoundtripRgbOklab("red", [255.0, 0.0, 0.0])
diagRoundtripRgbOklab("green", [0.0, 255.0, 0.0])
diagRoundtripRgbOklab("blue", [0.0, 0.0, 255.0])
diagRoundtripRgbOklab("yellow",[255.0, 255.0, 0.0])
}
输出中的 residual 三元组即为往返残差。若你的场景对黄的蓝通道有严格约束,请考虑:
- 将插值/映射路径置于 Lab/Luv;或
- 提升近似迭代次数/使用更高精度的数学实现(需结合性能评估)。
8. 性能与精度建议
- 本库在常用路径上采用近似例程以提升性能(gamma 编码/解码、cbrt、pow/root、三角函数等)。
- 若你偏好更高精度,可在关键路径中替换或扩展迭代次数(需评估对整体性能影响)。
- 处理高饱和颜色时要留意多步近似带来的误差累积,必要时对输出做钳制或采用更宽松的容差。
9. 常见坑与规避
- 值域:RGB 0…255;线性/近线性空间 0…100;角度单位为度(Degrees)。
- Option:绝大多数 API 返回 ?T,任何失败都可能返回 None,务必 match 处理。
- 字符串:CSS3/4 支持空格+斜杠 alpha 语法,注意百分比与小数 alpha 的混用。
- 空间名:字符串不区分大小写,但建议统一小写以减少混淆。
- 插值空间:为追求感知均匀的渐变,优先考虑 OKLab/Lab;RGB 插值更直观但效果可能不够均匀。
10. 测试与 CI(推荐)
- 使用项目自带的空间往返测试思路,结合你自身业务空间做少量用例。
- 针对 OKLab,可参考本库的 25.0 容差阈值(仅用于往返断言),在你的业务下按需调整。
- 在 CI 中运行 cjpm build 与 cjpm test(若有),保障基础功能稳定。
11. FAQ
- 支持的颜色字符串?见 doc/feature_api.md 与 README.md,涵盖 hex/rgb()/rgba()/hsl()/hwb()/cmyk()/命名颜色等。
- 是否支持 CSS4 命名颜色?支持 X11/HTML/NTC 等字典;CSS Color Module Level 4 命名作为参考。
- 是否有 Coloroid/OSA-UCS 等专业空间?有,详见 space/* 与 API 文档。
12. 更多接口案例
- 解析/标准化深度示例
package tutorial.color4cj.parse_more
import color4cj.parse.parseToRgbaFloat
import color4cj.parse.parseSpace
import color4cj.parse.parseDetailed
import color4cj.normalize.normalize
main() {
// 直接得到 RGBA(Float64),alpha 为 0..1
match (parseToRgbaFloat("hsl(210 100% 50% / 0.25)")) {
case Some(rgbaF) => println("parseToRgbaFloat => [${rgbaF[0]}, ${rgbaF[1]}, ${rgbaF[2]}], a=${rgbaF[3]}\n")
case None => println("parseToRgbaFloat failed\n")
}
// 拆分空间标签与数值
match (parseSpace("#00ff88")) {
case Some(sp) => println("parseSpace => ${sp}\n")
case None => println("parseSpace failed\n")
}
match (parseDetailed("rgb(140 200 100 / 50%)")) {
case Some(vals) => println("parseDetailed => [${vals[0]}, ${vals[1]}, ${vals[2]}, ${vals[3]}]\n")
case None => println("parseDetailed failed\n")
}
// 标准化到 uint8(返回 Float64 容器,但值域按 0..255 表示)
match (normalize("rgba(255,0,0,50%)", "uint8")) {
case Some(v) => println("normalize uint8 => [${v[0]}, ${v[1]}, ${v[2]}], a=${v[3]}\n")
case None => println("normalize uint8 failed\n")
}
}
- RGB 专用入口案例
package tutorial.color4cj.rgb_entry
import color4cj.space.toRgb
import color4cj.space.fromRgb
main() {
// HSL -> RGB(使用 RGB 专用入口)
match (toRgb("hsl", [96.0, 0.48, 0.59])) {
case Some(rgb) => println("toRgb(hsl) => [${rgb[0]}, ${rgb[1]}, ${rgb[2]}]\n")
case None => println("toRgb(hsl) failed\n")
}
// RGB -> LRGB -> RGB 往返
match (fromRgb("lrgb", [140.0, 200.0, 100.0])) {
case Some(lrgb) => {
println("fromRgb(lrgb) => [${lrgb[0]}, ${lrgb[1]}, ${lrgb[2]}]\n")
match (toRgb("lrgb", lrgb)) {
case Some(rgb2) => println("lrgb->rgb => [${rgb2[0]}, ${rgb2[1]}, ${rgb2[2]}]\n")
case None => println("lrgb->rgb failed\n")
}
}
case None => println("fromRgb(lrgb) failed\n")
}
}
- 命名颜色字典查询
package tutorial.color4cj.dicts
import color4cj.colors.getX11Hex
import color4cj.colors.getHtmlHex
import color4cj.colors.getNtcHex
import color4cj.colors.getPantoneHex
import color4cj.colors.getRoygbivHex
import color4cj.colors.getBasicHex
main() {
match (getX11Hex("CornflowerBlue")) { case Some(h) => println("X11 => ${h}") case None => println("X11 => None") }
match (getHtmlHex("CornflowerBlue")) { case Some(h) => println("HTML => ${h}") case None => println("HTML => None") }
match (getNtcHex("CornflowerBlue")) { case Some(h) => println("NTC => ${h}") case None => println("NTC => None") }
match (getPantoneHex("PANTONE 100 C")) { case Some(h) => println("Pantone => ${h}") case None => println("Pantone => None") }
match (getRoygbivHex("orange")) { case Some(h) => println("Roygbiv => ${h}") case None => println("Roygbiv => None") }
match (getBasicHex("red")) { case Some(h) => println("Basic => ${h}") case None => println("Basic => None") }
}
- 扩展空间转换案例集
package tutorial.color4cj.space_cases
import color4cj.space.convert
func show(label: String, vals: ?Array<Float64>): Void {
match (vals) {
case Some(v) => println("${label} => [${v[0]}, ${v[1]}, ${v[2]}]")
case None => println("${label} => None")
}
}
main() {
// 经典空间
show("hsl->rgb", convert("hsl", "rgb", [30.0, 0.5, 0.5]))
show("hsv->rgb", convert("hsv", "rgb", [210.0, 0.7, 0.8]))
show("hwb->rgb", convert("hwb", "rgb", [120.0, 0.1, 0.2]))
show("cmyk->rgb", convert("cmyk", "rgb", [30.0, 0.0, 50.0, 22.0]))
// 感知/线性空间
show("rgb->xyz", convert("rgb", "xyz", [140.0, 200.0, 100.0]))
show("xyz->lab", convert("xyz", "lab", [20.0, 20.0, 20.0]))
show("lab->lchab", convert("lab", "lchab", [50.0, 40.0, 20.0]))
show("luv->lchuv", convert("luv", "lchuv", [50.0, 20.0, 30.0]))
show("xyz->xyy", convert("xyz", "xyy", [20.0, 20.0, 20.0]))
show("xyz->lms", convert("xyz", "lms", [20.0, 20.0, 20.0]))
show("xyz->ucs", convert("xyz", "ucs", [20.0, 20.0, 20.0]))
show("xyz->uvw", convert("xyz", "uvw", [20.0, 20.0, 20.0]))
show("rgb->lrgb", convert("rgb", "lrgb", [140.0, 200.0, 100.0]))
show("rgb->oklab", convert("rgb", "oklab", [140.0, 200.0, 100.0]))
// 其他空间
show("hsluv->rgb", convert("hsluv", "rgb", [210.0, 60.0, 60.0]))
show("hpluv->rgb", convert("hpluv", "rgb", [210.0, 60.0, 60.0]))
show("cubehelix->rgb", convert("cubehelix", "rgb", [300.0, 1.0, 1.0]))
show("xvycc->rgb", convert("xvycc", "rgb", [50.0, 20.0, 20.0]))
show("ciecam->xyz", convert("ciecam", "xyz", [50.0, 20.0, 20.0]))
}
13. 总结
color4cj 适合在 UI/可视化/图形工具中快速上线颜色处理能力。你可以先用统一 convert 路由完成跨空间转换,再逐步引入插值、字符串化与诊断工具,根据业务需要在性能与精度之间做权衡。若你希望我为你的具体场景定制性能策略或插值方案,也欢迎进一步交流。# 仓颉三方库实战教程:用 color4cj 处理颜色 🎨
本文是一篇面向仓颉(Cangjie)开发者的实战教程,手把手教你在项目中集成与使用 color4cj 库,完成颜色字符串解析、标准化、跨空间转换与插值等常见需求,并结合数值诊断与性能建议,帮助你快速落地。
提示:本文示例以 color4cj v0.0.2 与 Cangjie v1.0.3+ 为参考,若你的版本不同,API 行为可能略有差异,请以项目 README.md 与 doc/feature_api.md 为准。
1. 为什么选 color4cj?
- 覆盖广:原生支持 30+ 常见与专业色彩空间的双向转换。
- 易集成:统一 convert 路由与 toRgb/fromRgb 入口,降低 API 学习成本。
- 开箱即用:解析与标准化支持 CSS3/4 语法与命名颜色,简单字符串即可运行。
- 结果友好:提供 RGBA 数值与字符串化工具,易于与前端/UI 渲染衔接。
2. 获取与引入
你可以通过两种方式将 color4cj 引入到你的项目中:
方式 A:本地路径依赖(适合同仓或本地开发)
# cjpm.toml(示例)
[dependencies]
color4cj = { path = "../color4cj" }
方式 B:Git 依赖(适合跨仓复用)
# cjpm.toml(示例)
[dependencies]
color4cj = { git = "https://gitcode.com/cj-awaresome/color4cj.git", tag = "v0.0.2" }
注意:依赖写法可能随 cjpm 版本演进,请以你当前的 cjpm 文档为准。若暂无注册仓库,你也可以直接复制需要的模块或使用子模块管理。
3. 快速上手(Hello Color)
示例:解析/标准化/字符串化,再做空间转换与插值。
package tutorial.color4cj.hello
import color4cj.parse.parseColorToRgb
import color4cj.parse.parseAlpha
import color4cj.normalize.normalize
import color4cj.normalize.normalizeString
import color4cj.rgba.rgba
import color4cj.rgba.rgbaString
import color4cj.space.convert
import color4cj.interpolate.interpolateAt
import color4cj.interpolate.interpolateStringSpace
main() {
// 解析命名颜色
match (parseColorToRgb("CornflowerBlue")) {
case Some(rgb) => println("name => [${rgb[0]}, ${rgb[1]}, ${rgb[2]}], a=${parseAlpha("CornflowerBlue")}\n")
case None => println("parse name failed\n")
}
// 标准化到数组(RGBA Float64)
match (normalize("rgba(255,0,0,50%)", "array")) {
case Some(v) => println("normalize array => [${v[0]}, ${v[1]}, ${v[2]}], a=${v[3]}\n")
case None => println("normalize array failed\n")
}
// 字符串化(保持输入风格或转为 rgba(...))
match (normalizeString("CornflowerBlue")) {
case Some(s) => println("normalizeString => ${s}\n")
case None => println("normalizeString failed\n")
}
// 空间转换:RGB -> OKLab
match (convert("rgb", "oklab", [255.0, 0.0, 0.0])) {
case Some(oklab) => println("rgb→oklab => [${oklab[0]}, ${oklab[1]}, ${oklab[2]}]\n")
case None => println("convert rgb→oklab failed\n")
}
// 插值:在 RGB 与 OKLab 中对比效果
let palette: Array<String> = ["red", "rgba(0,0,255,0.5)", "#00ff00"]
match (interpolateAt(palette, 0.25)) {
case Some(rgbaF) => println("RGB interpolate t=0.25 => [${rgbaF[0]}, ${rgbaF[1]}, ${rgbaF[2]}], a=${rgbaF[3]}\n")
case None => println("RGB interpolate failed\n")
}
match (interpolateStringSpace(palette, 0.5, "oklab")) {
case Some(s) => println("OKLab interpolate t=0.5 => ${s}\n")
case None => println("OKLab interpolate failed\n")
}
}
构建与运行:
cjpm update
cjpm build
cjpm run
测试用例执行:
cjpm test

4. 统一路由与范围约定(必读)
- convert(spaceFrom, spaceTo, values):适用于多数空间间的转换;空间字符串不区分大小写。
- toRgb/fromRgb:RGB 专用入口,约定 RGB 使用 0…255 范围。
- 线性/近线性空间(XYZ/LMS/UCS/UVW/Lab/Luv/OKLab 等)通常使用 0…100 范围;角度单位为度。
- 返回值均为 Option(?T):转换失败或不可达时返回 None,请在 match 中处理。
5. 插值策略如何选?
- RGB:直觉友好、实现简单,但可能在高饱和过渡中产生非感知均匀的路径。
- Lab/Luv:历史经典方案,相较 RGB 更接近感知均匀,但不同显示与白点假设下表现差异。
- OKLab:近年较受欢迎的感知空间之一,插值路径更自然;在高饱和复合原色(如黄)往返时可能存在少量残差(见第 7 章)。
建议:对 UI/可视化渐变,优先尝试 OKLab 或 Lab;对兼容性与性能要求高的场景,可在 RGB 插值后做一次到目标空间的映射。
6. 字符串化与命名颜色
- rgba(cstr): 将字符串解析为 RGBA(Float64),alpha 范围 0…1。
- rgbaString/rgbaStringFixed: 产出 rgb()/rgba() 字符串,便于拼接到前端样式或导出。
- getColorRgb(name): 大小写不敏感查询命名颜色,支持 X11/HTML/NTC/Pantone/Roygbiv/Basic。
7. 数值诊断:OKLab 往返残差与排查
在高饱和复合原色(尤其是黄)上,OKLab 的往返可能出现少量残差。这源于近似数值例程(cbrt/幂/gamma)的累计误差与常量精度限制。本库在测试中将往返断言容差调整到 25.0 以保证可逆性与工程可用性。
你可以在自己的项目里增加一个小工具,帮助定位与量化残差:
package tutorial.color4cj.diag
import color4cj.space.rgbToOklab
import color4cj.space.oklabToRgb
public func diagRoundtripRgbOklab(label: String, rgb: Array<Float64>): Void {
match (rgbToOklab(rgb)) {
case Some(oklab) => {
match (oklabToRgb(oklab)) {
case Some(rgb2) => {
let dx = rgb2[0] - rgb[0]
let dy = rgb2[1] - rgb[1]
let dz = rgb2[2] - rgb[2]
println("[${label}] rgb=[${rgb[0]},${rgb[1]},${rgb[2]}] -> rgb2=[${rgb2[0]},${rgb2[1]},${rgb2[2]}], residual=[${dx},${dy},${dz}]\n")
}
case None => println("oklabToRgb failed\n")
}
}
case None => println("rgbToOklab failed\n")
}
}
main() {
diagRoundtripRgbOklab("red", [255.0, 0.0, 0.0])
diagRoundtripRgbOklab("green", [0.0, 255.0, 0.0])
diagRoundtripRgbOklab("blue", [0.0, 0.0, 255.0])
diagRoundtripRgbOklab("yellow",[255.0, 255.0, 0.0])
}
输出中的 residual 三元组即为往返残差。若你的场景对黄的蓝通道有严格约束,请考虑:
- 将插值/映射路径置于 Lab/Luv;或
- 提升近似迭代次数/使用更高精度的数学实现(需结合性能评估)。
8. 性能与精度建议
- 本库在常用路径上采用近似例程以提升性能(gamma 编码/解码、cbrt、pow/root、三角函数等)。
- 若你偏好更高精度,可在关键路径中替换或扩展迭代次数(需评估对整体性能影响)。
- 处理高饱和颜色时要留意多步近似带来的误差累积,必要时对输出做钳制或采用更宽松的容差。
9. 常见坑与规避
- 值域:RGB 0…255;线性/近线性空间 0…100;角度单位为度(Degrees)。
- Option:绝大多数 API 返回 ?T,任何失败都可能返回 None,务必 match 处理。
- 字符串:CSS3/4 支持空格+斜杠 alpha 语法,注意百分比与小数 alpha 的混用。
- 空间名:字符串不区分大小写,但建议统一小写以减少混淆。
- 插值空间:为追求感知均匀的渐变,优先考虑 OKLab/Lab;RGB 插值更直观但效果可能不够均匀。
10. 测试与 CI(推荐)
- 使用项目自带的空间往返测试思路,结合你自身业务空间做少量用例。
- 针对 OKLab,可参考本库的 25.0 容差阈值(仅用于往返断言),在你的业务下按需调整。
- 在 CI 中运行 cjpm build 与 cjpm test(若有),保障基础功能稳定。
11. FAQ
- 支持的颜色字符串?见 doc/feature_api.md 与 README.md,涵盖 hex/rgb()/rgba()/hsl()/hwb()/cmyk()/命名颜色等。
- 是否支持 CSS4 命名颜色?支持 X11/HTML/NTC 等字典;CSS Color Module Level 4 命名作为参考。
- 是否有 Coloroid/OSA-UCS 等专业空间?有,详见 space/* 与 API 文档。
12. 更多接口案例
- 解析/标准化深度示例
package tutorial.color4cj.parse_more
import color4cj.parse.parseToRgbaFloat
import color4cj.parse.parseSpace
import color4cj.parse.parseDetailed
import color4cj.normalize.normalize
main() {
// 直接得到 RGBA(Float64),alpha 为 0..1
match (parseToRgbaFloat("hsl(210 100% 50% / 0.25)")) {
case Some(rgbaF) => println("parseToRgbaFloat => [${rgbaF[0]}, ${rgbaF[1]}, ${rgbaF[2]}], a=${rgbaF[3]}\n")
case None => println("parseToRgbaFloat failed\n")
}
// 拆分空间标签与数值
match (parseSpace("#00ff88")) {
case Some(sp) => println("parseSpace => ${sp}\n")
case None => println("parseSpace failed\n")
}
match (parseDetailed("rgb(140 200 100 / 50%)")) {
case Some(vals) => println("parseDetailed => [${vals[0]}, ${vals[1]}, ${vals[2]}, ${vals[3]}]\n")
case None => println("parseDetailed failed\n")
}
// 标准化到 uint8(返回 Float64 容器,但值域按 0..255 表示)
match (normalize("rgba(255,0,0,50%)", "uint8")) {
case Some(v) => println("normalize uint8 => [${v[0]}, ${v[1]}, ${v[2]}], a=${v[3]}\n")
case None => println("normalize uint8 failed\n")
}
}
- RGB 专用入口案例
package tutorial.color4cj.rgb_entry
import color4cj.space.toRgb
import color4cj.space.fromRgb
main() {
// HSL -> RGB(使用 RGB 专用入口)
match (toRgb("hsl", [96.0, 0.48, 0.59])) {
case Some(rgb) => println("toRgb(hsl) => [${rgb[0]}, ${rgb[1]}, ${rgb[2]}]\n")
case None => println("toRgb(hsl) failed\n")
}
// RGB -> LRGB -> RGB 往返
match (fromRgb("lrgb", [140.0, 200.0, 100.0])) {
case Some(lrgb) => {
println("fromRgb(lrgb) => [${lrgb[0]}, ${lrgb[1]}, ${lrgb[2]}]\n")
match (toRgb("lrgb", lrgb)) {
case Some(rgb2) => println("lrgb->rgb => [${rgb2[0]}, ${rgb2[1]}, ${rgb2[2]}]\n")
case None => println("lrgb->rgb failed\n")
}
}
case None => println("fromRgb(lrgb) failed\n")
}
}
- 命名颜色字典查询
package tutorial.color4cj.dicts
import color4cj.colors.getX11Hex
import color4cj.colors.getHtmlHex
import color4cj.colors.getNtcHex
import color4cj.colors.getPantoneHex
import color4cj.colors.getRoygbivHex
import color4cj.colors.getBasicHex
main() {
match (getX11Hex("CornflowerBlue")) { case Some(h) => println("X11 => ${h}") case None => println("X11 => None") }
match (getHtmlHex("CornflowerBlue")) { case Some(h) => println("HTML => ${h}") case None => println("HTML => None") }
match (getNtcHex("CornflowerBlue")) { case Some(h) => println("NTC => ${h}") case None => println("NTC => None") }
match (getPantoneHex("PANTONE 100 C")) { case Some(h) => println("Pantone => ${h}") case None => println("Pantone => None") }
match (getRoygbivHex("orange")) { case Some(h) => println("Roygbiv => ${h}") case None => println("Roygbiv => None") }
match (getBasicHex("red")) { case Some(h) => println("Basic => ${h}") case None => println("Basic => None") }
}
- 扩展空间转换案例集
package tutorial.color4cj.space_cases
import color4cj.space.convert
func show(label: String, vals: ?Array<Float64>): Void {
match (vals) {
case Some(v) => println("${label} => [${v[0]}, ${v[1]}, ${v[2]}]")
case None => println("${label} => None")
}
}
main() {
// 经典空间
show("hsl->rgb", convert("hsl", "rgb", [30.0, 0.5, 0.5]))
show("hsv->rgb", convert("hsv", "rgb", [210.0, 0.7, 0.8]))
show("hwb->rgb", convert("hwb", "rgb", [120.0, 0.1, 0.2]))
show("cmyk->rgb", convert("cmyk", "rgb", [30.0, 0.0, 50.0, 22.0]))
// 感知/线性空间
show("rgb->xyz", convert("rgb", "xyz", [140.0, 200.0, 100.0]))
show("xyz->lab", convert("xyz", "lab", [20.0, 20.0, 20.0]))
show("lab->lchab", convert("lab", "lchab", [50.0, 40.0, 20.0]))
show("luv->lchuv", convert("luv", "lchuv", [50.0, 20.0, 30.0]))
show("xyz->xyy", convert("xyz", "xyy", [20.0, 20.0, 20.0]))
show("xyz->lms", convert("xyz", "lms", [20.0, 20.0, 20.0]))
show("xyz->ucs", convert("xyz", "ucs", [20.0, 20.0, 20.0]))
show("xyz->uvw", convert("xyz", "uvw", [20.0, 20.0, 20.0]))
show("rgb->lrgb", convert("rgb", "lrgb", [140.0, 200.0, 100.0]))
show("rgb->oklab", convert("rgb", "oklab", [140.0, 200.0, 100.0]))
// 其他空间
show("hsluv->rgb", convert("hsluv", "rgb", [210.0, 60.0, 60.0]))
show("hpluv->rgb", convert("hpluv", "rgb", [210.0, 60.0, 60.0]))
show("cubehelix->rgb", convert("cubehelix", "rgb", [300.0, 1.0, 1.0]))
show("xvycc->rgb", convert("xvycc", "rgb", [50.0, 20.0, 20.0]))
show("ciecam->xyz", convert("ciecam", "xyz", [50.0, 20.0, 20.0]))
}
13. 总结
color4cj 适合在 UI/可视化/图形工具中快速上线颜色处理能力。你可以先用统一 convert 路由完成跨空间转换,再逐步引入插值、字符串化与诊断工具,根据业务需要在性能与精度之间做权衡。若你希望我为你的具体场景定制性能策略或插值方案,也欢迎进一步交流。
新一代开源开发者平台 GitCode,通过集成代码托管服务、代码仓库以及可信赖的开源组件库,让开发者可以在云端进行代码托管和开发。旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。
更多推荐



所有评论(0)