Serialize Color as srgb (#1136)

This commit is contained in:
Dennis Kobert 2023-04-16 15:02:22 +02:00 committed by Keavon Chambers
parent b626d39035
commit f68bc42fc9
3 changed files with 18 additions and 9 deletions

View file

@ -102,16 +102,14 @@ pub trait Pixel: Clone + Pod + Zeroable {
bytemuck::bytes_of(self).to_vec() bytemuck::bytes_of(self).to_vec()
} }
// TODO: use u8 for Color // TODO: use u8 for Color
fn from_bytes(bytes: &[u8]) -> &Self { fn from_bytes(bytes: &[u8]) -> Self {
bytemuck::try_from_bytes(bytes).expect("Failed to convert bytes to pixel") *bytemuck::try_from_bytes(bytes).expect("Failed to convert bytes to pixel")
} }
fn byte_size() -> usize { fn byte_size() -> usize {
std::mem::size_of::<Self>() std::mem::size_of::<Self>()
} }
} }
impl<T: Serde + Clone + Pod + Zeroable> Pixel for T {}
pub trait RGB: Pixel { pub trait RGB: Pixel {
type ColorChannel: Channel; type ColorChannel: Channel;
fn red(&self) -> Self::ColorChannel; fn red(&self) -> Self::ColorChannel;

View file

@ -12,7 +12,7 @@ use spirv_std::num_traits::Euclid;
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use super::{Alpha, AssociatedAlpha, Luminance, Rec709Primaries, RGB, SRGB}; use super::{Alpha, AssociatedAlpha, Luminance, Pixel, Rec709Primaries, RGB, SRGB};
/// Structure that represents a color. /// Structure that represents a color.
/// Internally alpha is stored as `f32` that ranges from `0.0` (transparent) to `1.0` (opaque). /// Internally alpha is stored as `f32` that ranges from `0.0` (transparent) to `1.0` (opaque).
@ -52,6 +52,16 @@ impl RGB for Color {
} }
} }
impl Pixel for Color {
fn to_bytes(&self) -> Vec<u8> {
self.to_rgba8_srgb().to_vec()
}
fn from_bytes(bytes: &[u8]) -> Self {
Color::from_rgba8_srgb(bytes[0], bytes[1], bytes[2], bytes[3])
}
}
impl Alpha for Color { impl Alpha for Color {
type AlphaChannel = f32; type AlphaChannel = f32;
fn alpha(&self) -> f32 { fn alpha(&self) -> f32 {
@ -514,8 +524,9 @@ impl Color {
/// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap(); /// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap();
/// //TODO: Add test /// //TODO: Add test
/// ``` /// ```
pub fn to_rgba8(&self) -> [u8; 4] { pub fn to_rgba8_srgb(&self) -> [u8; 4] {
[(self.red * 255.) as u8, (self.green * 255.) as u8, (self.blue * 255.) as u8, (self.alpha * 255.) as u8] let gamma = self.to_gamma_srgb();
[(gamma.red * 255.) as u8, (gamma.green * 255.) as u8, (gamma.blue * 255.) as u8, (gamma.alpha * 255.) as u8]
} }
// https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/ // https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/

View file

@ -5,7 +5,7 @@ use graphene_core::Node;
fn apply_mask(image_frame: &mut ImageFrame<Color>, x: usize, y: usize, multiplier: u8) { fn apply_mask(image_frame: &mut ImageFrame<Color>, x: usize, y: usize, multiplier: u8) {
let color = &mut image_frame.image.data[y * image_frame.image.width as usize + x]; let color = &mut image_frame.image.data[y * image_frame.image.width as usize + x];
let color8 = color.to_rgba8(); let color8 = color.to_rgba8_srgb();
*color = Color::from_rgba8_srgb(color8[0] * multiplier, color8[1] * multiplier, color8[2] * multiplier, color8[3] * multiplier); *color = Color::from_rgba8_srgb(color8[0] * multiplier, color8[1] * multiplier, color8[2] * multiplier, color8[3] * multiplier);
} }
@ -90,7 +90,7 @@ fn convert_image_to_mask(input: &ImageFrame<Color>) -> Vec<u8> {
let mut last_value = 0_usize; let mut last_value = 0_usize;
for (color, result) in input.image.data.iter().zip(result.iter_mut()) { for (color, result) in input.image.data.iter().zip(result.iter_mut()) {
let color = color.to_rgba8(); let color = color.to_rgba8_srgb();
if let Some(value) = colors.get(&color) { if let Some(value) = colors.get(&color) {
*result = *value as u8; *result = *value as u8;
} else { } else {