Add the Mask node (#1080)

* Add MaskImageNode

Co-authored-by: Dennis Kobert <dennis@kobert.dev>
This commit is contained in:
isiko
2023-04-09 04:56:03 +02:00
committed by Keavon Chambers
parent 9e8ac42a82
commit 8677981ceb
7 changed files with 56 additions and 4 deletions

View File

@@ -44,7 +44,7 @@ fn map_gpu_single_image(input: Image, node: String) -> Image {
nodes: [(
0,
DocumentNode {
name: "Image filter Node".into(),
name: "Image Filter".into(),
inputs: vec![NodeInput::Network(concrete!(Color))],
implementation: DocumentNodeImplementation::Unresolved(identifier),
metadata: DocumentNodeMetadata::default(),

View File

@@ -194,6 +194,40 @@ fn compute_transformed_bounding_box(transform: DAffine2) -> Bbox {
}
}
#[derive(Debug, Clone, Copy)]
pub struct MaskImageNode<Mask> {
mask: Mask,
}
#[node_macro::node_fn(MaskImageNode)]
fn mask_image(mut image: ImageFrame, mask: ImageFrame) -> ImageFrame {
let image_size = DVec2::new(image.image.width as f64, image.image.height as f64);
let mask_size = DVec2::new(mask.image.width as f64, mask.image.height as f64);
if mask_size == DVec2::ZERO {
return image;
}
// Transforms a point from the background image to the forground image
let bg_to_fg = DAffine2::from_scale(mask_size) * mask.transform.inverse() * image.transform * DAffine2::from_scale(1. / image_size);
for y in 0..image.image.height {
for x in 0..image.image.width {
let image_point = DVec2::new(x as f64, y as f64);
let mut mask_point = bg_to_fg.transform_point2(image_point);
mask_point = mask_point.clamp(DVec2::ZERO, mask_size);
let image_pixel = image.get_mut(x as usize, y as usize);
let mask_pixel = mask.sample(mask_point);
let alpha = image_pixel.a() * mask_pixel.r();
*image_pixel = Color::from_rgbaf32(image_pixel.r(), image_pixel.g(), image_pixel.b(), alpha).unwrap();
}
}
image
}
#[derive(Debug, Clone, Copy)]
pub struct BlendImageNode<Background, MapFn> {
background: Background,