lazygit 依赖解析:go-colorful 颜色空间转换、距离度量与调色板生成实战指南
本文以 lazygit 仓库中 vendored 的第三方库 go-colorful 的官方 README(README 原文)为主体,完整梳理该库支持的颜色空间、API 用法、距离度量与调色板生成原理,并结合 lazygit 源码中真实的调用点(作者名称着色)说明它在终端 UI 项目里的落地方式。读完后你可以掌握 Go 环境下颜色空间互转、感知距离比较、自然过渡插值以及“可区分随机调色板”的完整实现路径。
1. go-colorful 是什么:lazygit 的颜色基础设施
go-colorful 是一个用 Go 编写的颜色处理库,支持 Go 1.13 及以上版本。其设计动机来自作者做游戏时的一个细节问题:服务器给玩家随机分配颜色时,两个玩家经常拿到极其相近的颜色。作者受 "I want hue" 工具的启发,决定在 Go 生态里实现一个严肃的颜色空间处理库,并让它实现 Go 标准库的 color.Color 接口。
在 lazygit 仓库中,该库以 v1.4.1 版本被声明为直接依赖(见 go.mod 中的 github.com/lucasb-eyer/go-colorful v1.4.1),源码完整 vendor 在 vendor/github.com/lucasb-eyer/go-colorful 目录下,包含:
- colors.go:核心的
Color类型与 RGB/HSL/HVX/Xyz/Xyy/Lab/Luv/Hcl/Oklab/Oklch 各空间转换、距离与插值函数; - hsluv.go:HSLuv / HPLuv 颜色空间实现;
- widegamut.go:Display P3、A98Rgb、ProPhotoRgb、Rec2020 等广色域插值;
- soft_palettegen.go、warm_palettegen.go、happy_palettegen.go:Soft/Warm/Happy 调色板生成器;
- sort.go:
Sorted颜色排序函数; - hexcolor.go:
HexColor数据库存取类型。
从源码结构看,lazygit 与终端渲染层 tcell v3(fit.go 中也引用了它)都依赖这个库完成终端调色板适配,而 lazygit 自身的着色逻辑直接调用了它的构造器,具体见本文第 11 节。
2. 支持的颜色空间一览
go-colorful 内部以 sRGB(三个分量均在 0–1)存储颜色,核心类型定义在 colors.go:
// A color is stored internally using sRGB (standard RGB) values in the range 0-1
type Color struct {
R, G, B float64
}
在其之上,库提供了多种颜色空间表示。以下是 README 给出的完整清单及取值范围:
| 颜色空间 | 分量与范围 | 说明 |
|---|---|---|
| RGB | R/G/B 均在 [0..1] | 内部存储格式 |
| HSL | H 在 [0..360],S/L 在 [0..1] | 历史遗留;作者建议忘掉它的存在 |
| HSV | H 在 [0..360],S/V 在 [0..1] | 能用 HCL 替代时优先用 HCL |
| Hex RGB | 如 #FF00FF |
"互联网"颜色格式 |
| Linear RGB | 各分量 | 用于 gamma 校正渲染等物理计算 |
| CIE-XYZ | 接近 [0..1] | CIE 标准颜色空间 |
| CIE-xyY | x、y 为色度,Y 为亮度,均在 [0..1] | 色度 + 亮度编码 |
| CIE-L*a*b* | L* 在 [0..1],a*、b* 接近 [-1..1] | 感知均匀空间,距离有意义 |
| CIE-L*u*v* | 与 L*a*b* 类似 | 学术上无共识哪个"更好" |
| CIE-L*C*h°(HCL) | H° 在 [0..360],C* 接近 [0..1],L* 同 L*a*b* | 通常最实用;L*a*b* 的极坐标形式,即"更好的 HSV" |
CIE LCh(uv)(代码中为 LuvLCh) |
H° 在 [0..360],C* 接近 [0..1],L* 同 L*u*v* | L*u*v* 空间的圆柱化变换 |
| HSLuv | H 在 [0..360],S/L 在 [0..1] | 更好的 HSL 替代品,保证同色相下明度恒定 |
| HPLuv | 同 HSLuv 变体 | 色域更平滑,但只包含粉彩色(pastel);因有效范围受限,饱和度过高的颜色无法表示 |
| Oklab | L 在 [0..1],a、b 大致在 [-0.5..0.5] | Björn Ottosson 提出的感知空间,蓝色区域均匀性优于 L*a*b* |
| Oklch | L 在 [0..1],C 大致 [0..0.5],h° 在 [0..360] | Oklab 的圆柱(极坐标)表示 |
两点补充约定:
-
默认参考白点为 D65。对 XYZ、Lab、Luv、HCL 这些有意义的空间,库默认使用 D65 参考白,但提供了使用自定义参考白点(如 D50)的方法。参考白变量直接定义在源码中(colors.go):
var D65 = [3]float64{0.95047, 1.00000, 1.08883} var D50 = [3]float64{0.96422, 1.00000, 0.82521} -
"almost in range" 的含义:坐标"大致"落在某个范围,但对极亮的颜色、或在特定参考白下可能略微越界。例如
#0000ff的 C* 值为 1.338,超过了 1.0。
3. 应该选哪个颜色空间?
README 给出了一个经典的三句话判断法则(源自 I want hue 团队):
- RGB 契合"屏幕如何产生"颜色;
- CIE-L*a*b* 契合"人类如何感知"颜色;
- HCL 契合"人类如何思考"颜色。
因此经验法则是:凡是会用到 HSV 的场景,尽量改用 CIE-L*C*h°——在 L* 与 C* 固定的情况下旋转色相角 h°,颜色会沿着"感知亮度与强度相同"的路径变化。
4. 安装与基础用法
安装只需一行:
$ go get github.com/lucasb-eyer/go-colorful
引入后即可使用。构造同一个蓝色(#517AB8)可以用任意一种源颜色空间,它们应当彼此等价:
// Any of the following should be the same
c := colorful.Color{0.313725, 0.478431, 0.721569}
c, err := colorful.Hex("#517AB8")
if err != nil {
log.Fatal(err)
}
c = colorful.Hsv(216.0, 0.56, 0.722)
c = colorful.Xyz(0.189165, 0.190837, 0.480248)
c = colorful.Xyy(0.219895, 0.221839, 0.190837)
c = colorful.Lab(0.507850, 0.040585, -0.370945)
c = colorful.Luv(0.507849, -0.194172, -0.567924)
c = colorful.Hcl(276.2440, 0.373160, 0.507849)
c = colorful.OkLab(0.577227, -0.021391, -0.104541)
c = colorful.OkLch(0.577227, 0.106707, 258.435657)
fmt.Printf("RGB values: %v, %v, %v", c.R, c.G, c.B)
对应地,从该颜色反向转换回各颜色空间:
hex := c.Hex()
h, s, v := c.Hsv()
x, y, z := c.Xyz()
x, y, Y := c.Xyy()
l, a, b := c.Lab()
l, u, v := c.Luv()
h, c, l := c.Hcl()
l, a, b = c.OkLab()
l, c, h = c.OkLch()
README 特别提示了一个 Go 命名上的小坑:由于 Go 要求首字母大写的限制,与 xyY 空间相关的函数命名并不完全规范(如 Xyy),作者也公开征集更好的命名建议。上述各构造器在源码中均可直接定位,例如 Hsv(colors.go#L191)、Hsl(#L278)、Hex(#L367)、Lab(#L658)、Hcl(#L960)、OkLab(#L1065)、OkLch(#L1111)。
color.Color 接口与 MakeColor
colorful.Color 实现了标准库 image/color 的 color.Color 接口(RGBA() 方法将分量放大到 16 位,见 colors.go#L17-L23),因此可以直接传给任何接受 color.Color 的标准库 API。反向转换用 MakeColor:
c, ok := colorful.MakeColor(color.Gray16{12345})
注意边界情况:color.Color 使用预乘 alpha(pre-multiplied alpha),当 alpha 恰好为 0 时 RGB 分量在接口层面已被置 0,无法恢复,此时 MakeColor 返回 (Color{}, false)。这一点在 colors.go#L26-L42 中有明确实现:a == 0 时直接返回失败。
5. 颜色比较:为什么不能在 RGB 空间比距离
在 RGB 空间中,两色之间的欧氏距离不对应视觉感知距离:两组颜色在 RGB 空间距离相同,人眼却可能觉得一组远得多。解决这个问题正是 CIE-L*a*b*、CIE-L*u*v* 与 CIE-L*C*h° 存在的意义——比较颜色只应在这几类空间里做。(L*a*b* 与 L*C*h° 的距离相同,因为二者是同一空间的不同坐标表示。)
库提供的距离度量包括 DistanceRgb、DistanceLab(即 CIE76)、DistanceLuv、DistanceCIE94、DistanceCIEDE2000(以及带 kL/kC/kH 系数的 DistanceCIEDE2000klch)等。README 用一个四色对比程序演示了差异:
c1a := colorful.Color{150.0 / 255.0, 10.0 / 255.0, 150.0 / 255.0}
c1b := colorful.Color{53.0 / 255.0, 10.0 / 255.0, 150.0 / 255.0}
c2a := colorful.Color{10.0 / 255.0, 150.0 / 255.0, 50.0 / 255.0}
c2b := colorful.Color{99.9 / 255.0, 150.0 / 255.0, 10.0 / 255.0}
fmt.Printf("DistanceRgb: c1: %v\tand c2: %v\n", c1a.DistanceRgb(c1b), c2a.DistanceRgb(c2b))
fmt.Printf("DistanceLab: c1: %v\tand c2: %v\n", c1a.DistanceLab(c1b), c2a.DistanceLab(c2b))
fmt.Printf("DistanceLuv: c1: %v\tand c2: %v\n", c1a.DistanceLuv(c1b), c2a.DistanceLuv(c2b))
fmt.Printf("DistanceCIE76: c1: %v\tand c2: %v\n", c1a.DistanceCIE76(c1b), c2a.DistanceCIE76(c2b))
fmt.Printf("DistanceCIE94: c1: %v\tand c2: %v\n", c1a.DistanceCIE94(c1b), c2a.DistanceCIE94(c2b))
fmt.Printf("DistanceCIEDE2000: c1: %v\tand c2: %v\n", c1a.DistanceCIEDE2000(c1b), c2a.DistanceCIEDE2000(c2b))
运行结果(摘自 README):
DistanceRgb: c1: 0.3803921568627451 and c2: 0.3858713931171159
DistanceLab: c1: 0.32048458312798056 and c2: 0.24397151758565272
DistanceLuv: c1: 0.5134369614199698 and c2: 0.2568692839860636
DistanceCIE76: c1: 0.32048458312798056 and c2: 0.24397151758565272
DistanceCIE94: c1: 0.19799168128511324 and c2: 0.12207136371167401
DistanceCIEDE2000: c1: 0.17274551120971166 and c2: 0.10665210031428465
上排两色人眼觉得差别大得多,但 RGB 距离(0.3804 vs 0.3859)几乎相同;Lab 距离(0.3205 vs 0.2440)开始拉开差距,CIEDE2000 则给出最贴近感知且区分度最好的数值。这组数据说明:DistanceLab 只是更正式名称 DistanceCIE76 的别名,已被更精确(但代价更高)的 DistanceCIE94 与 DistanceCIEDE2000 取代。
另外,AlmostEqualRgb 主要面向(单元)测试场景,README 用一句玩笑式的警告提醒你:只有确实知道自己在做什么时才使用它。
6. 颜色混合(Blending):插值空间的选择决定渐变质感
混合与距离是同一枚硬币的两面:插值本质上是"走过"某个颜色空间,空间对距离映射得越好,走起来越"平滑"。
各空间混合效果对比
库内置了 RGB、Linear RGB、HSV、Lab、Luv、Hcl、LuvLCh、Oklab、Oklch,以及广色域(Display P3、A98Rgb、ProPhotoRgb、Rec2020,见 widegamut.go)等混合函数。以 #fdffcc 渐变到 #242a42 为例,README 给出了各空间的实际表现结论:
- HSV 非常差:中间出现了源颜色中根本不存在的绿色;
- RGB 明显更好,但亮度过高保持了太久;
- LUV 与 LAB 都能命中正确的亮度,LAB 还多保留一点色彩;
- HCL 与 HSV 同属圆柱插值,但 HCL 做对了——不出现杂色,亮度线性变化。
生成 README 中对比图的示例程序(源码位于上游仓库 doc/colorblend/colorblend.go)核心逻辑如下,可直接复制运行:
package main
import (
"fmt"
"github.com/lucasb-eyer/go-colorful"
"image"
"image/draw"
"image/png"
"os"
)
func main() {
blocks := 10
blockw := 40
img := image.NewRGBA(image.Rect(0, 0, blocks*blockw, 200))
c1, _ := colorful.Hex("#fdffcc")
c2, _ := colorful.Hex("#242a42")
// Use these colors to get invalid RGB in the gradient.
//c1, _ := colorful.Hex("#EEEF61")
//c2, _ := colorful.Hex("#1E3140")
for i := 0; i < blocks; i++ {
draw.Draw(img, image.Rect(i*blockw, 0, (i+1)*blockw, 40), &image.Uniform{c1.BlendHsv(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
draw.Draw(img, image.Rect(i*blockw, 40, (i+1)*blockw, 80), &image.Uniform{c1.BlendLuv(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
draw.Draw(img, image.Rect(i*blockw, 80, (i+1)*blockw, 120), &image.Uniform{c1.BlendRgb(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
draw.Draw(img, image.Rect(i*blockw, 120, (i+1)*blockw, 160), &image.Uniform{c1.BlendLab(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
draw.Draw(img, image.Rect(i*blockw, 160, (i+1)*blockw, 200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
// This can be used to "fix" invalid colors in the gradient.
//draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1)).Clamped()}, image.Point{}, draw.Src)
}
toimg, err := os.Create("colorblend.png")
if err != nil {
fmt.Printf("Error: %v", err)
return
}
defer toimg.Close()
png.Encode(toimg, img)
}
关键陷阱:CIE 空间插值可能产生非法 RGB
在任意 CIE 空间插值时,中间结果可能不是合法 RGB 颜色——当起止颜色来自用户输入或随机生成时尤其危险。典型反例是 #eeef61 到 #1e3140 的渐变会在底部产生偏红的非法色。处理手段在源码中很明确(colors.go#L67-L82):
// Checks whether the color exists in RGB space, i.e. all values are in [0..1]
func (c Color) IsValid() bool {
return 0.0 <= c.R && c.R <= 1.0 &&
0.0 <= c.G && c.G <= 1.0 &&
0.0 <= c.B && c.B <= 1.0
}
// Clamps the color into valid range, clamping each value to [0..1]
func (c Color) Clamped() Color {
return Color{clamp01(c.R), clamp01(c.G), clamp01(c.B)}
}
即:用 IsValid() 检测、用 Clamped() 取最近的合法颜色来"修复"渐变。README 强调这是一个"满足但不完美"的补救——钳位会牺牲渐变端点的颜色准确性。
生成渐变
混合最常见的用途就是做渐变:取若干控制色,按 t ∈ [0..1] 依次调用 BlendHcl(或其他空间的 Blend)即可。README 指向上游 doc/gradientgen/gradientgen.go 中一个 HCL 空间的 "Spectral" 色带生成示例,其 API 与上面的混合示例完全一致,没有引入新函数。
7. 随机颜色与随机调色板
随机颜色
不必在 RGB 里硬拉随机数。把随机值限制在 [0..1] 的更小子区间内,再配合 CIE-L*C*h° 或 HSV 空间,就能得到"同一色相的随机深浅"或"指定亮度的随机颜色":
random_blue := colorful.Hcl(180.0+rand.Float64()*50.0, 0.2+rand.Float64()*0.8, 0.3+rand.Float64()*0.7)
random_dark := colorful.Hcl(rand.Float64()*360.0, rand.Float64(), rand.Float64()*0.4)
random_light := colorful.Hcl(rand.Float64()*360.0, rand.Float64(), 0.6+rand.Float64()*0.4)
针对"温暖"(warm)和"快乐"(happy)这类高频需求,库提供了专用函数:
colorful.WarmColor()
colorful.HappyColor()
colorful.FastWarmColor()
colorful.FastHappyColor()
带 Fast 前缀的版本更快但一致性较差——它们在 HSV 空间取样;普通版在 CIE-L*C*h° 空间取样,感知上更均匀。README 提醒:务必先初始化随机种子。
随机调色板
需要多个随机颜色时,你真正想要的是彼此可区分的颜色(和几乎同色的对手对战并不有趣)。库用专门算法保证调色板内所有颜色尽可能区分开。同样分 Fast(HSV,感知均匀性较差)与非 Fast(CIE 空间)两套。除了 Warm / Happy 版本,还有一个可配置性更强的 Soft 版本:
简单方法只接收颜色数量(例如玩家数),返回 []Color:
pal1, err1 := colorful.WarmPalette(10)
pal2 := colorful.FastWarmPalette(10)
pal3, err3 := colorful.HappyPalette(10)
pal4 := colorful.FastHappyPalette(10)
pal5, err5 := colorful.SoftPalette(10)
注意:非 Fast 方法在索取过多颜色时可能失败(返回 error)。对应的实现可分别参见 warm_palettegen.go、happy_palettegen.go 与 soft_palettegen.go。
进阶 API SoftPaletteEx 额外接收一个 SoftPaletteSettings,关键成员有三个:
CheckColor:一个func(l, a, b float64) bool,对落在目标颜色区域内的颜色返回true,否则false——这就是"约束颜色感受"的机制;Iteration:建议设在 [5..100],越大越慢但调色板越精确;ManySamples:当你的CheckColor拒绝了颜色空间的大部分区域时,设为true以增加采样量。
例如生成 10 个棕色调:
func isbrowny(l, a, b float64) bool {
h, c, L := colorful.LabToHcl(l, a, b)
return 10.0 < h && h < 50.0 && 0.1 < c && c < 0.5 && L < 0.5
}
// 上面的约束比较严格,因此设置 ManySamples 为 true
brownies := colorful.SoftPaletteEx(10, colorful.SoftPaletteSettings{isbrowny, 50, true})
其理论背景可参考 "I want hue" 项目的说明(非 Fast 路径的核心算法来源)。
8. 颜色排序:Sorted
颜色排序本身不是良定义的操作:{深蓝, 深红, 浅蓝, 浅红} 在"深色优先"下已有序,在"长波长优先"下则要重排。
库提供的 Sorted 函数(sort.go#L153)采用另一种目标:排序后使相邻颜色之间的平均距离最小(首尾相邻也计入)。它不保证找到真正的最小值,只给出一个相当接近的近似。README 用一张 512 随机色的示意图说明了三种排法的差异:按通道排序(先 L 后 h 再 C)会产生刺眼的"细条纹"图案——事实上用任何颜色空间、任何通道顺序都会如此;而 Sorted 的结果看似无序,但整体过渡明显更平滑。
9. Linear RGB 与性能:Fast 近似路径
RGB ↔ Linear RGB 有两套变换:一个快而近似精确,一个慢而完全精确:
r, g, b := colorful.Hex("#FF0000").FastLinearRgb()
FAQ 对此有完整解释:Lab/Luv/HCl 等转换慢,是因为它们都要经过使用幂运算的 LinearRgb。库作者用泰勒近似实现了 FastLinearRgb,快约 5 倍,精度约 0.5%;主要缺点是输入值超出 [0..1] 范围时精度骤降。在紧循环中可手动组合快速路径,例如:
col := // Get your color somehow
l, a, b := XyzToLab(LinearRgbToXyz(col.LinearRgb()))
README 同时说明:该库以正确性、可读性与模块化为优先,并非为速度而写;进一步的提速空间在 SIMD 指令,或针对特定转换整体做近似,但后者超出该库的职责边界。推导过程可参考上游仓库的 doc/LinearRGB Approximations.ipynb 笔记本及其精度曲线图。
10. 其他实用能力
自定义参考白点
c := colorful.LabWhiteRef(0.507850, 0.040585, -0.370945, colorful.D50)
l, a, b := c.LabWhiteRef(colorful.D50)
从数据库读写颜色
HexColor 类型实现了 database/sql.Scanner 与 database/sql/driver.Value 接口,可自动完成字符串与颜色之间的类型转换,便于把颜色以 hex 字符串形式入库:
var hc HexColor
_, err := db.QueryRow("SELECT '#ff0000';").Scan(&hc)
// hc == HexColor{R: 1, G: 0, B: 0}; err == nil
类型定义见 hexcolor.go。
11. 实战落点:lazygit 如何用 go-colorful 给作者名着色
在 lazygit 中,提交列表里每位作者的名字都有确定性的专属颜色。实现位于 pkg/gui/presentation/authors/authors.go:
func trueColorStyle(str string) style.TextStyle {
hash := md5.Sum([]byte(str))
c := colorful.Hsl(randFloat(hash[0:4])*360.0, 0.6+0.4*randFloat(hash[4:8]), 0.4+randFloat(hash[8:12])*0.2)
return style.New().SetFg(style.NewRGBColor(style.NewRGBColor(color.RGB(uint8(c.R*255), uint8(c.G*255), uint8(c.B*255)))))
}
这段代码恰好印证了 go-colorful 的几个核心 API:
- 确定性"随机":对作者名做 MD5,把哈希字节切成三段,各映射到 HSL 的一个分量——色相取全范围 [0..360),饱和度限制在 [0.6, 1.0],亮度限制在 [0.4, 0.6]。这正是第 7 节"约束随机颜色"思想的确定性变体:同名作者永远同色,且颜色不会太暗(亮度下限 0.4)或太艳(饱和度上限 1.0)。
Hsl构造器:对应 colors.go#L278 的func Hsl(h, s, l float64) Color。- Color 分量回读:结果
c.R/c.G/c.B再乘以 255 转成终端 RGB 颜色;等价于RGB255()便捷方法(colors.go#L45-L50)的手写版本。
此外,该文件通过 authorStyleCache(map[string]*style.TextStyle)缓存作者样式,并在通配符键 "*" 上支持统一风格;SetCustomAuthors 则允许用户通过配置覆盖默认着色逻辑,避免重算哈希。从源码结构看,终端渲染层 tcell v3 的调色板拟合逻辑(fit.go)同样直接构造 colorful.Color,说明该库是整个 lazygit 颜色管线的底层依赖,而不只是作者着色这一处。
12. FAQ:README 官方澄清的三个高频问题
Q:我得到的数值全乱了! A:多半是数值范围给错了。RGB 分量期望是 [0..1],不是 [0..255]。先归一化你的颜色。
Q:Lab/Luv/HCl 看起来坏了!
A:你很可能在生成显示器根本无法表示的颜色。例如请求 HCL(190.0, 1.0, 1.0).RGB255(),实际的 RGB 值是 (-2105.254, 300.680, 286.185),这样的值根本不存在;RGB255 只是把这些数强转 uint8,产生回绕,看起来就像完全坏掉的渐变。正确做法是改用 RGB 中真实存在的合理颜色值,或者对结果 Clamp() 到最近的合法颜色并接受其后果:HCL(190.0, 1.0, 1.0).Clamp().RGB255()。
Q:紧循环里 Lab/Luv/HCl 转换太慢了!
A:是的,它们就是慢。可用 FastLinearRgb(泰勒近似,快约 5 倍、精度约 0.5%)替换转换链中的 LinearRgb;README 还欢迎社区为 Distance* / Blend* 提交基于该快速近似的 PR。
Q:为什么 MakeColor 会失败?
A:alpha 通道为 0 时失败,此时转换未定义(见第 4 节的 Caveat 说明)。
13. 小结:选型速查
| 任务 | 推荐空间 / 函数 | 备注 |
|---|---|---|
| 屏幕渲染取值 | RGB / Hex |
分量 [0..1] |
| 感知距离比较 | Lab / Luv / HCL,优先 DistanceCIE94 或 DistanceCIEDE2000 |
RGB 距离无感知意义 |
| 平滑渐变 / 混合 | BlendHcl、BlendLab(CIE 系) |
结果需用 IsValid() + Clamped() 兜底 |
| 固定亮度/强度转色相 | HCL(Hcl 构造器) |
"更好的 HSV" |
| 同色相随机深浅 | HCL + 受限随机区间 | lazygit 作者着色即此模式 |
| 多色互不混淆 | SoftPalette / WarmPalette / HappyPalette(非 Fast 系) |
颜色数过多可能失败 |
| 带约束的调色板 | SoftPaletteEx + CheckColor(l, a, b) |
Iteration ∈ [5..100],约束严格时设 ManySamples |
| 无序颜色平滑排布 | Sorted |
最小化相邻平均距离的近似解 |
| 高性能循环 | FastLinearRgb 组合精确转换 |
精度约 0.5%,输入须落在 [0..1] |
go-colorful 通过 vendor 目录完整随仓库分发,所有上述函数都可以直接在 vendor/github.com/lucasb-eyer/go-colorful 下对照源码阅读,配合 CHANGELOG.md 与 MIT 许可(LICENSE)使用。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00