Color system based on traits, and conversion to linear color in the graph (#1123)

* Migrate Nodes to use RasterMut + Samplable

* Add Pixel trait to include serialization

* Implement traits for Color and propagate new generics

* Always convert to linear color when loading images
This commit is contained in:
Dennis Kobert
2023-04-16 02:57:05 +02:00
committed by GitHub
parent e4d4f4ad68
commit 59db45bb36
16 changed files with 638 additions and 265 deletions
@@ -12,6 +12,7 @@ use document_legacy::LayerId;
use document_legacy::Operation as DocumentOperation;
use graph_craft::document::NodeId;
use graphene_core::raster::Image;
use graphene_core::Color;
use serde::{Deserialize, Serialize};
#[remain::sorted]
@@ -122,7 +123,7 @@ pub enum DocumentMessage {
resize_opposite_corner: Key,
},
PasteImage {
image: Image,
image: Image<Color>,
mouse: Option<(f64, f64)>,
},
Redo,
@@ -34,7 +34,7 @@ use document_legacy::layers::text_layer::Font;
use document_legacy::{DocumentError, DocumentResponse, LayerId, Operation as DocumentOperation};
use graph_craft::document::NodeId;
use graph_craft::{concrete, Type, TypeDescriptor};
use graphene_core::raster::{Color, ImageFrame};
use graphene_core::raster::{Color, ImageFrame, RasterMut};
use graphene_core::Cow;
use glam::{DAffine2, DVec2};
@@ -1057,7 +1057,7 @@ impl DocumentMessageHandler {
let primary_input_type = node_network.input_types().next().clone();
let response = match primary_input_type {
// Only calclate the frame if the primary input is an image
Some(ty) if ty == concrete!(ImageFrame) => {
Some(ty) if ty == concrete!(ImageFrame<Color>) => {
// Calculate the size of the region to be exported
let old_transforms = self.remove_document_transform();
let transform = self.document_legacy.multiply_transforms(&layer_path).unwrap();
@@ -113,8 +113,8 @@ fn static_nodes() -> Vec<DocumentNodeType> {
nodes: [
DocumentNode {
name: "Downres".to_string(),
inputs: vec![NodeInput::Network(concrete!(ImageFrame))],
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_std::raster::DownresNode")),
inputs: vec![NodeInput::Network(concrete!(ImageFrame<Color>))],
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_std::raster::DownresNode<_>")),
metadata: Default::default(),
},
DocumentNode {
@@ -160,7 +160,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
outputs: vec![NodeOutput::new(0, 0), NodeOutput::new(1, 0)],
nodes: [DocumentNode {
name: "Identity".to_string(),
inputs: vec![NodeInput::Network(concrete!(ImageFrame))],
inputs: vec![NodeInput::Network(concrete!(ImageFrame<Color>))],
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IdNode")),
metadata: Default::default(),
}]
@@ -174,7 +174,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
DocumentInputType {
name: "In",
data_type: FrontendGraphDataType::General,
default: NodeInput::Network(concrete!(ImageFrame)),
default: NodeInput::Network(concrete!(ImageFrame<Color>)),
},
DocumentInputType::value("Transform", TaggedValue::DAffine2(DAffine2::IDENTITY), false),
],
@@ -193,7 +193,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
nodes: [
DocumentNode {
name: "SetNode".to_string(),
inputs: vec![NodeInput::Network(concrete!(ImageFrame))],
inputs: vec![NodeInput::Network(concrete!(ImageFrame<Color>))],
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::SomeNode")),
metadata: Default::default(),
},
@@ -277,7 +277,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
DocumentNodeType {
name: "Image Frame",
category: "General",
identifier: NodeImplementation::proto("graphene_std::raster::ImageFrameNode<_>"),
identifier: NodeImplementation::proto("graphene_std::raster::ImageFrameNode<_, _>"),
inputs: vec![
DocumentInputType::value("Image", TaggedValue::Image(Image::empty()), true),
DocumentInputType::value("Transform", TaggedValue::DAffine2(DAffine2::IDENTITY), true),
@@ -288,7 +288,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
DocumentNodeType {
name: "Mask",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::raster::MaskImageNode<_>"),
identifier: NodeImplementation::proto("graphene_std::raster::MaskImageNode<_, _, _>"),
inputs: vec![
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Stencil", TaggedValue::ImageFrame(ImageFrame::empty()), true),
@@ -419,7 +419,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
0,
DocumentNode {
name: "CacheNode".to_string(),
inputs: vec![NodeInput::Network(concrete!(Image))],
inputs: vec![NodeInput::Network(concrete!(Image<Color>))],
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_std::memo::CacheNode")),
metadata: Default::default(),
},
@@ -489,7 +489,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
0,
DocumentNode {
name: "CacheNode".to_string(),
inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::Network(concrete!(ImageFrame))],
inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::Network(concrete!(ImageFrame<Color>))],
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_std::memo::CacheNode")),
metadata: Default::default(),
},
@@ -954,7 +954,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
transform: glam::DAffine2::IDENTITY,
});
// Compute the transform input to the node graph frame
let image_frame: graphene_core::raster::ImageFrame = context.executor.compute_input(context.network, &imaginate_node, 0, image_frame).unwrap_or_default();
let image_frame: graphene_core::raster::ImageFrame<Color> = context.executor.compute_input(context.network, &imaginate_node, 0, image_frame).unwrap_or_default();
let transform = image_frame.transform;
let resolution = {
@@ -205,7 +205,7 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
let r = (random_number >> 16) as u8;
let g = (random_number >> 8) as u8;
let b = random_number as u8;
let random_color = Color::from_rgba8(r, g, b, 255);
let random_color = Color::from_rgba8_srgb(r, g, b, 255);
document_data.primary_color = random_color;
document_data.update_working_colors(responses);