#color #color-conversion #rgb #hsv #cie #graphics

prisma

一个用于简单和复杂颜色操作的库,旨在成为大多数任务的首选 Rust 颜色库。它能够处理多种颜色模型之间的转换,并可以转换到 CIE 设备无关的颜色空间。Prisma 旨在易于使用的同时鼓励正确的转换,使数学上正确的转换变得容易,而无需了解整个颜色科学领域。

2 个版本

0.1.1 2020 年 7 月 19 日
0.1.0 2020 年 7 月 18 日

#303图像

Download history 82/week @ 2024-04-22 57/week @ 2024-04-29 68/week @ 2024-05-06 70/week @ 2024-05-13 55/week @ 2024-05-20 62/week @ 2024-05-27 46/week @ 2024-06-03 64/week @ 2024-06-10 62/week @ 2024-06-17 73/week @ 2024-06-24 12/week @ 2024-07-01 44/week @ 2024-07-08 192/week @ 2024-07-15 62/week @ 2024-07-22 47/week @ 2024-07-29 47/week @ 2024-08-05

每月 353 次下载
4 crate 中使用

MIT 许可证

520KB
14K SLoC

Prisma - Rust 颜色库

Build Status

目录

概述

Prisma 是一个 Rust 库,旨在提供一套全面的颜色表示、操作、转换和算法,易于用于各种级别的项目。Prisma 遵循“选择”复杂性的模式,这意味着如果您只想有一个库将 Rgb 转换为 Hsv 并返回,Prisma 将允许您在不了解整个颜色科学领域的情况下以最小的知识完成它。但是,如果您需要访问 CIE 空间或进行颜色空间转换,Prisma 也提供该功能,并使用包装器来使用类型系统强制执行有效性。

Prisma 致力于成为 Rust 中颜色转换和颜色科学的必备资源。它目前正在开发中,任何贡献或功能请求都受到欢迎。

颜色模型

目前 Prisma 支持以下颜色模型

设备相关

  • Rgb - 显示的标准颜色模型
  • Rgi - 从 Rgb 构造的色度模型,将色度和亮度分离
  • Hsv - 色调、饱和度、值:一个更直观的极坐标 Rgb 模型
  • Hsl - 色调、饱和度、亮度:Hsv 的替代品,履行类似角色
  • Hsi - 色调、饱和度、强度:一个基于色调且无失真的模型
  • eHsi - 对 Hsi 的扩展,重新调整饱和度以避免在 RGB 中超出色域
  • Hwb - 色调、白度、黑度:一个基于色调的模型,便于用户选择颜色
  • YCbCr - 用于显示和广播的各种 YUV 和 YIQ 模型的表示

设备无关

  • Xyz - 作为其他颜色空间定义基准的“父”绝对颜色空间
  • Lms - 模拟人类锥体反应的颜色空间
  • Lab - XYZ 的均匀感知颜色空间转换
  • Lchab - Lab 的极坐标变换。类似于 Hsl 的均匀感知模拟
  • Luv - 在照明计算中有用的替代均匀感知颜色空间
  • Lchuv - Luv 的极坐标变换

Prisma 还通过 Alpha 类型支持带有 Alpha 通道的颜色空间。

为什么选择 Prisma?

目前,有两个主要的 Rust 颜色库

  • color -- color 是一个非常旧的库,已经几年没有更新了。虽然它可以通过几个颜色空间进行转换,并且易于使用,但它具有非常有限的功能集。

  • palette -- palette 具有更多功能,并且可以进入一些 CIE 空间,但要求所有计算都在线性编码中进行是一个严重的缺点,因为如果你只想在游戏中获得一个好看的渐变,线性 Hsv 是 不会 给你那个的。它还建立在预定义的模型之上,不支持动态配置。prisma 支持更多的颜色空间,以及多种编码和可以在运行时构建的空间。prisma 还不需要你指定颜色空间,因为大多数应用程序实际上并不关心,并且使用设备颜色空间或 sRgb。

Prisma 旨在支持上述库的所有功能,同时让用户决定他们需要多少复杂性。

示例导览

从 Rgb 转换到 Hsv,操作色调,然后再转换回来
#[macro_use] extern crate approx;
extern crate angular_units as angle;
# extern crate prisma;

use prisma::{Rgb, Hsv, FromColor};
use angle::Deg;

let rgb = Rgb::new(0.5, 0.75, 1.0);
let mut hsv = Hsv::from_color(&rgb);
hsv.set_hue(Deg(180.0));
let rgb = Rgb::from_color(&hsv);
assert_relative_eq!(rgb, Rgb::new(0.5, 1.0, 1.0), epsilon=1e-6);
在 Hsl 之间插值两种颜色。
#[macro_use] extern crate approx;
extern crate angular_units as angle;
# extern crate prisma;

use prisma::{Rgb, Hsl, FromColor, Lerp};
use angle::Deg;

let rgb1 = Rgb::new(0.8, 0.25, 0.0f32);
let rgb2 = Rgb::new(0.5, 0.66, 1.0);
// Specify the hue channel should use degrees
let hsl1: Hsl<_, Deg<f32>> = Hsl::from_color(&rgb1);
let hsl2 = Hsl::from_color(&rgb2);
// Note that hue channels will interpolate in the shortest direction. This is usually
// the expected behavior, but you can always go forward with `lerp_flat`.
let rgb_out = Rgb::from_color(&hsl1.lerp(&hsl2, 0.35));
assert_relative_eq!(rgb_out, Rgb::new(1.0, 0.045, 0.62648), epsilon=1e-4);
从 Rgb 转换到 Rgb
#[macro_use] extern crate approx;
# extern crate prisma;

use prisma::Rgb;

let rgb_in = Rgb::new(100, 200, 255u8);
let rgb_out: Rgb<f32> = rgb_in.color_cast();
assert_relative_eq!(rgb_out, Rgb::new(0.39216, 0.78431, 1.0), epsilon=1e-4);
将 sRgb 编码转换为线性编码 Rgb
#[macro_use] extern crate approx;
# extern crate prisma;

use prisma::Rgb;
use prisma::encoding::{EncodableColor, TranscodableColor, SrgbEncoding};

// This returns a `EncodedColor<Rgb<f32>, SrgbEncoding>`
// Note: no encodind is done. `srgb_encoded` says that this value is already in sRgb encoding.
let rgb_srgb = Rgb::new(0.5, 1.0, 0.25f32).srgb_encoded();
// Decode goes from an encoding to linear.
let rgb_linear = rgb_srgb.clone().decode();
assert_relative_eq!(rgb_linear, Rgb::new(0.21404, 1.0, 0.05088).linear(), epsilon=1e-4);
// We can then go back with `encode`
let rgb_out = rgb_linear.encode(SrgbEncoding);
assert_relative_eq!(rgb_out, rgb_srgb, epsilon=1e-6);
转换为 XYZ
#[macro_use] extern crate approx;
# extern crate prisma;

use prisma::{Rgb, Xyz};
use prisma::encoding::{EncodableColor, TranscodableColor};
use prisma::color_space::{ColorSpace, EncodedColorSpace, NamedColorSpace, ConvertToXyz};
use prisma::color_space::presets::sRgb;

let rgb = Rgb::new(0.25, 0.5, 0.75f32).srgb_encoded();
let color_space = sRgb::get_color_space();
// In this case, since rgb and color_space know their own encodings, the conversion to linear
// is automatic.
let xyz = color_space.convert_to_xyz(&rgb);
assert_relative_eq!(xyz, Xyz::new(0.191803, 0.201605, 0.523050), epsilon=1e-5);

依赖项

~225KB