本文是一篇面向仓颉(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

img

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. 更多接口案例

  1. 解析/标准化深度示例
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")
    }
}
  1. 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")
    }
}
  1. 命名颜色字典查询
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") }
}
  1. 扩展空间转换案例集
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

img

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. 更多接口案例

  1. 解析/标准化深度示例
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")
    }
}
  1. 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")
    }
}
  1. 命名颜色字典查询
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") }
}
  1. 扩展空间转换案例集
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 路由完成跨空间转换,再逐步引入插值、字符串化与诊断工具,根据业务需要在性能与精度之间做权衡。若你希望我为你的具体场景定制性能策略或插值方案,也欢迎进一步交流。

Logo

新一代开源开发者平台 GitCode,通过集成代码托管服务、代码仓库以及可信赖的开源组件库,让开发者可以在云端进行代码托管和开发。旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐