现代JavaScript颜色处理库 高效精准轻量级
@texel/color是一个现代JavaScript颜色处理库,为实时应用、生成艺术和网页图形提供高效解决方案。该库支持快速颜色转换、色差计算、色域映射和序列化,在速度和精确度方面表现出色。支持OKLCH、DisplayP3等现代颜色空间,并可通过tree-shaking优化包体积。相比其他类似库,性能提升5-125倍,内存占用更低。
这是一个简洁现代的JavaScript颜色库。特别适用于实时应用、生成艺术和网页图形。
使用npm安装并导入模块。
npm install @texel/color --save
将OKLCH(OKLab的圆柱形式)转换为sRGB:
import { convert, OKLCH, sRGB } from "@texel/color"; // L = 0 .. 1 // C = 0 .. 0.4 // H = 0 .. 360(度) const rgb = convert([0.5, 0.15, 30], OKLCH, sRGB); // 注意sRGB输出范围为0 .. 1 // -> [ 0.658, 0.217, 0.165 ]
你也可以使用通配符导入:
import * as colors from "@texel/color"; const rgb = colors.convert([0.5, 0.15, 30], colors.OKLCH, colors.sRGB);
:bulb: 现代打包工具(esbuild、vite)会应用树摇,移除未使用的功能,如代码中未引用的色彩空间和色域映射函数。上述脚本使用esbuild打包后约3.5kb。
另一个使用色域映射和序列化的宽色域Canvas2D示例:
import { gamutMapOKLCH, DisplayP3Gamut, sRGBGamut, serialize } from "@texel/color"; // 可能在或不在sRGB色域内的值 const oklch = [ 0.15, 0.425, 30 ]; // 决定要映射到哪个色域 const isDisplayP3Supported = /* 检查环境 */; const gamut = isDisplayP3Supported ? DisplayP3Gamut : sRGBGamut; // 将输入的OKLCH映射到R,G,B空间(sRGB或DisplayP3) const rgb = gamutMapOKLCH(oklch, gamut); // 获取输出空间的CSS颜色字符串 const color = serialize(rgb, gamut.space); // 在Canvas2D上下 文中绘制颜色 const canvas = document.createElement('canvas'); const context = canvas.getContext('2d', { colorSpace: gamut.id }); context.fillStyle = color; context.fillRect(0,0, canvas.width, canvas.height);
output = convert(coords, fromSpace, toSpace, output = [0, 0, 0])
将coords
(通常为[r,g,b]
或[l,c,h]
等)从fromSpace
转换到指定的toSpace
。from和to空间是spaces接口之一。
你可以传入output
,一个三维向量,结果将存储在其中。这可用于避免在热代码路径中分配新内存。
返回值是目标空间的新坐标;如sRGB
空间的目标为[r,g,b]
。注意,大多数空间使用归一化且无界的坐标;所以RGB空间的范围是0..1,可能会超出范围(即超出色域)。你可能需要结合gamutMapOKLCH
使用,见下文。
output = gamutMapOKLCH(oklch, gamut = sRGBGamut, targetSpace = gamut.space, out = [0, 0, 0], mapping = MapToCuspL, [cusp])
执行Björn Ottoson描述的(2021)快速OKLCH色域映射。接受OKLCH空间的输入[l,c,h]
坐标,确保最终结果在指定的颜色gamut
内(默认sRGBGamut
)。你可以进一步指定不同的目标空间(默认为色域的空间),例如获取线性光sRGB并避免传递函数,或保持结果在OKLCH中:
import { gamutMapOKLCH, sRGBGamut, sRGBLinear, OKLCH } from "@texel/color"; // 映射到sRGB但返回线性sRGB const lrgb = gamutMapOKLCH(oklch, sRGBGamut, sRGBLinear); // 或映射到sRGB但返回OKLCH(不执行RGB裁剪) const lch = gamutMapOKLCH(oklch, sRGBGamut, OKLCH);
你可以指定out
数组以避免分配,结果将存储在该数组中。你还可以指定mapping
函数,决定色域映射时使用的策略,可以是以下之一:
import { // 可能的映射 MapToL, MapToGray, MapToCuspL, MapToAdaptiveGray, MapToAdaptiveCuspL, } from "@texel/color"; // 执行sRGB色域映射时保持亮度 const rgb = [0, 0, 0]; gamutMapOKLCH(oklch, sRGBGamut, sRGB, rgb, MapToL);
cusp
也可作为最后一个参数传入,允许对已知色相进行更快的评估。见下文计算cusp。
注意: 如果映射到基于OKLab的目标(OKLCH、OKHSL等),将跳过最后的RGB裁剪步骤。这会产生更可预测的OKLab和OKLCH结果,但在转换为可显示颜色时,你可能需要执行最后的clampedRGB()步骤。
LC = findCuspOKLCH(a, b, gamut, out = [0, 0])
找到给定OKLab色相平面(用OKLab空间中的归一化a
和b
值表示)的'cusp',返回[L, C]
(亮度和色度)。当你在已知色相上工作时,这对预计算色域映射的某些方面很有用:
import { sRGBGamut, findCuspOKLCH, gamutMapOKLCH, degToRad, MapToCuspL, } from "@texel/color"; const gamut = sRGBGamut; // 为这个色相计算一次cusp const H = 30; // 例如30º色相 const hueAngle = degToRad(H); const a = Math.cos(hueAngle); const b = Math.sin(hueAngle); const cuspLC = findCuspOKLCH(a, b, gamut); // ... 在程序的其他地方 ... // 传入'cusp'参数以 加快评估 // 假设你的OKLCH坐标与cusp有相同的色相(H) gamutMapOKLCH(oklch, gamut, gamut.space, out, MapToCuspL, cuspLC);
a
和b
也可以来自OKLab坐标,但必须归一化使a^2 + b^2 == 1
。
str = serialize(coords, inputSpace, outputSpace = inputSpace)
将指定的coords
(假定在inputSpace
中)转换为字符串,如果需要,先转换到指定的outputSpace
。如果空间是sRGB,为了浏览器兼容性和性能,将使用普通的rgb(r,g,b)
字符串(字节形式),否则将返回CSS颜色字符串。注意,并非所有空间(如某些线性空间)目前都受CSS支持。你可以选择在coords
数组中传入第四个元素作为alpha
分量(0..1范围)。
import { serialize, sRGB, DisplayP3, OKLCH } from "@texel/color"; serialize([0, 0.5, 1], sRGB); // "rgb(0, 128, 255)" serialize([0, 0.5, 1, 0.5], sRGB); // "rgba(0, 128, 255, 0.5)" serialize([0, 0.5, 1], DisplayP3); // "color(display-p3 0 0.5 1)" serialize([0, 0.5, 1, 0.35], DisplayP3); // "color(display-p3 0 0.5 1 / 0.35)" serialize([1, 0, 0], OKLCH, sRGB); // "rgb(255, 255, 255)" serialize([1, 0, 0], OKLCH); // "oklch(1 0 0)"
info = deserialize(colorString)
这是serialize
的反向操作,它会接收一个字符串,确定它引用的色彩空间id
,以及3个或4个(含透明度)coords
。这个功能有意地限制了范围,只支持十六进制RGB、rgb()
和rgba()
字节值,以及oklch()
、oklab()
和不带修饰符的普通color()
函数。
import { deserialize } from "@texel/color"; const { coords, id } = deserialize("color(display-p3 0 0.5 1 / 0.35)"); console.log(id); // "display-p3" console.log(coords); // [ 0, 0.5, 1, 0.35 ]
注意: 解析仍然是API设计中正在进行的工作,复杂的CSS颜色字符串处理不在本库的范围内。
delta = deltaEOK(oklabA, oklabB)
在OKLab空间中计算两个坐标之间的颜色差异。由于这是一个感知均匀的色彩空间,改进了CIELAB及其缺陷,因此在许多情况下它应该可以适当地替代CIEDE2000颜色差异方程。
[utils]
该模块还导出了许多其他实用工具。
该模块导出了一组色彩空间:
import { XYZ, // 使用D65白点 XYZD50, // 使用D50白点 sRGB, sRGBLinear, DisplayP3, DisplayP3Linear, Rec2020, Rec2020Linear, A98RGB, // Adobe® 1998 RGB A98RGBLinear, ProPhotoRGB, ProPhotoRGBLinear, OKLab, OKLCH, OKHSL, // 在sRGB色域内 OKHSV, // 在sRGB色域内 // 列出所有空间的函数 listColorSpaces, } from "@texel/color"; console.log(listColorSpaces()); // [XYZ, sRGB, sRGBLinear, ...] console.log(sRGBLinear.id); // "srgb-linear" console.log(sRGB.base); // -> sRGBLinear console.log(sRGB.fromBase(someLinearRGB)); // -> [gamma编码的sRGB...] console.log(sRGB.toBase(someGammaRGB)); // -> [线性sRGB...]
注意,并非所有空间都有base
字段;如果未指定,则假定色彩空间可以通过OKLab或XYZ作为根进行传递。
该模块导出了一组"色域",这些色域是由OKLab空间中的近似值定义的边界,允许快速进行色域映射。这些接口主要由gamutMapOKLCH
函数使用。
import { sRGBGamut, DisplayP3Gamut, Rec2020Gamut, A98RGBGamut, // 列出所有色域的函数 listColorGamuts, } from "@texel/color"; console.log(listColorGamuts()); // [sRGBGamut, ...] console.log(sRGBGamut.space); // sRGB空间 console.log(sRGBGamut.space.id); // 'srgb'
注意:目前尚不支持ProPhoto色域,我欢迎通过Python脚本修复它的PR。
除了核心API外,该模块还导出了许多实用工具:
b = floatToByte(f)
将0..1范围内的浮点数转换为0..255范围内的字节,进行四舍五入并限制在范围内。
out = XYZ_to_xyY(xyz, out=[0,0,0])
将XYZ坐标转换为xyY形式,如果指定了out
,则将结果存储在其中后返回。
out = xyY_to_XYZ(xyY, out=[0,0,0])
将xyY坐标转换为XYZ形式,如果指定了out
,则将结果存储在其中后返回。
v = lerp(min, max, t)
使用因子t
在min和max之间执行线性插值。
v = lerpAngle(min, max, t)
使用因子t
在min和max之间执行圆形线性插值,其中min和max被视为角度(以度为单位),允许值在0到360之间环绕,插值以创建最短的弧。
c = clamp(value, min, max)
将value
限制在min和max之间,并返回结果。
out = clampedRGB(inRGB, out=[0,0,0])
将RGB限制( 即裁剪)在0..1范围内,如果指定了out
,则将结果存储在其中后返回。
inside = isRGBInGamut(rgb, epsilon = 0.000075)
如果给定的rgb
在其0..1色域边界内,则返回true
,阈值为epsilon
。
rgb = hexToRGB(hex, out=[0,0,0])
将指定的十六进制字符串(带或不带前导#
)转换为0..1范围内的浮点RGB三元组,如果指定了out
,则将结果存储在其中后返回。
hex = RGBToHex(rgb)
将指定的RGB三元组(0..1范围内的浮点数)转换为带前导#
的6字符十六进制颜色字符串。
angle = constrainAngle(angle)
将angle
(以度为单位)限制在0..360范围内,必要时进行环绕。
degAngle = radToDeg(radAngle)
将角度(以弧度为单位)转换为度。
radAngle = degToRad(degAngle)
将角度(以度为单位)转换为弧度。
您还可以导入更低级别的函数和矩阵;这可能对细粒度转换有用,或者例如将缓冲区上传到WebGPU以进行计算着色器。
import { OKLab_to, OKLab_from, transform, XYZ_to_linear_sRGB_M, LMS_to_XYZ_M, XYZ_to_LMS_M, sRGB, OKHSLToOKLab, DisplayP3Gamut, } from "@texel/color"; console.log(XYZ_to_linear_sRGB_M); // [ [a,b,c], ... ] OKLab_to(oklab, LMS_to_XYZ_M); // OKLab -> XYZ D65 OKLab_from(xyzD65, XYZ_to_LMS_M); // XYZ D65 -> OKLab transform(xyzD65, XYZ_to_linear_sRGB_M); // XYZ D65 -> sRGBLinear sRGB.fromBase(in_linear_sRGB, out_sRGB); // 线性到gamma传递函数 sRGB.toBase(in_sRGB, out_linear_sRGB); // gamma到线性传递函数 // 非sRGB色域中的OKHSL // 另见OKHSVToOKLab及其反函数 OKHSLToOKLab([h, s, l], DisplayP3Gamut, optionalOutVec);
该库目前只公开了{ lerp, lerpAngle }
函数。要插值颜色,您需要构建一些额外的逻辑,例如,请参见example-interpolation.js脚本,该脚本在Canvas2D中创建颜色渐变。
您可以构建自定义色彩空间对象来扩展这个库,例如添加对CIELab和HSL的支持。有关示例,请参见test/spaces/lab.js和test/spaces/hsl.js。其中一些空间可能在以后添加到库中,尽管当前重点是"现代"空间(如OKLab,它在很大程度上使CIELab和HSL过时)。自定义色彩空间的文档正在编写中。
Colorjs非常出色,可能是JavaScript中当前领先的标准,但它对于创意编码和实时Web应用程序来说并不是很实用,在这些应用程序中,要求通常是(1)更精简的代码库,(2)高度优化,以及(3)最小化GC抖动。
Colorjs,以及类似的Culori,专注于匹配CSS规范,这意味着它很可能会随着时间的推移继续增加复杂性,性能通常会受到影响(例如,@texel/color
的尖点交叉色域映射比Colorjs快约125倍,比culori快约60倍)。
还有许多其他选项,如 color-space 或 color-convert,但这些不支持现代色彩空间,如 OKLab 和 OKHSL,和/或具有可疑的准确度(例如,许多库不区分 XYZ 中的 D50 和 D65 白点)。
本库并不旨在涵盖所有色彩空间;它只专注于有限的"现代"集合,即 OKLab、OKHSL 和 DeltaEOK 在许多实际用途中已经取代了 CIELab、HSL 和 CIEDE2000,使得本库更简单、更精简。请注意,其他空间如 CIELab 和 HSL 可通过"自定义色彩空间"得到支持。
该模块使用了以下一些做法,以显著优化性能并减小打包体积:
所有转换都经过测试,与 Colorjs 转换近似相等,误差在 2<sup>-33</sup>(10 位小数)以内,在某些情况下甚至更准确。
本库使用 coloraide 及其 Python 工具计算转换矩阵和 OKLab 色域近似值。一些矩阵已硬编码到脚本中,并尽可能使用有理数(如 CSS 颜色模块工作草案规范 中 建议 的那样)。
如果您认为矩阵或准确度可以改进,请提交 PR。
test 目录中有几个基准测试:
npm run bench
与 colorjs 进行比较npm run bench:node
获取 node 性能分析npm run bench:size
使用 esbuild 获取小型打包大小以下结果基于 MacBook Air M2。请注意,Colorjs 的性能取决于您使用的 API(默认的基于类的 API 比过程式 API 慢得多)。
<details> <summary>与 Colorjs.io 的基准对比</summary>转换(Colorjs.io 过程式 API)--
Colorjs.io:2955.88 毫秒
我们的:457.86 毫秒
加速:快 6.5 倍
转换(Colorjs.io 主要 API)--
Colorjs.io:10034.38 毫秒
我们的:452.11 毫秒
加速:快 22.2 倍
OKLCH - sRGB 色域映射(Colorjs.io 过程式 API)--
Colorjs.io:5602.46 毫秒
我们的:49.10 毫秒
加速:快 114.1 倍
OKLCH - sRGB 色域映射(Colorjs.io 主要 API)--
Colorjs.io:5913.80 毫秒
我们的:44.91 毫秒
加速:快 131.7 倍
所有空间到 P3 的色域映射(Colorjs.io 过程式 API)--
Colorjs.io:4693.43 毫秒
我们的:150.16 毫秒
加速:快 31.3 倍
所有空间到 P3 的色域映射(Colorjs.io 主要 API)--
Colorjs.io:5478.16 毫秒
我们的:145.88 毫秒
加速:快 37.6 倍
</details>
<details>
<summary>与 Culori 的基准对比</summary>
使用输入类型:OKLab L 平面的随机采样进行测试
OKLCH 到 P3 的转换 --
Culori:43.30 毫秒
我们的:12.83 毫秒
加速:快 3.4 倍
OKLCH 到 P3 色域的色域映射 --
Culori:1588.62 毫秒
我们的:23.05 毫秒
加速:快 68.9 倍
</details>
克隆,npm install
,然后运行 npm run
列出可用的脚本,或运行 npm t
执行测试。
这个库的实现得益于许多开发者和工程师的出色前期工作:
MIT 许可,详见 LICENSE.md。
字节跳动发布的AI编程神器IDE
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。
全能AI智能助手,随时解答生活与工作的多样问题
问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。
实时语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。
一键生成PPT和Word,让学习生活更轻松
讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。
深度推理能力全新升级,全面对标OpenAI o1
科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。
一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型
Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。
AI助力,做PPT更简单!
咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。
选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。
专业的AI公文写作平台,公文写作神器
AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。
OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。
openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。