CPKreuz před 1 rokem
rodič
revize
9dee88fefd

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Filter.cs

@@ -5,7 +5,7 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph;
 
 public sealed class Filter : IDisposable
 {
-    private Filter(ColorFilter? colorFilter, ImageFilter? imageFilter)
+    public Filter(ColorFilter? colorFilter, ImageFilter? imageFilter)
     {
         ColorFilter = colorFilter;
         ImageFilter = imageFilter;

+ 46 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/ApplyFilterNode.cs

@@ -0,0 +1,46 @@
+using PixiEditor.ChangeableDocument.Helpers;
+using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+
+namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+
+public class ApplyFilterNode : Node
+{
+    private Paint _paint = new();
+    
+    protected override string NodeUniqueName { get; } = "ApplyFilter";
+
+    public override string DisplayName { get; set; } = "APPLY_FILTER_NODE";
+    
+    public OutputProperty<Surface?> Output { get; }
+
+    public InputProperty<Surface?> Input { get; }
+    
+    public InputProperty<Filter?> Filter { get; }
+
+    public ApplyFilterNode()
+    {
+        Output = CreateOutput<Surface>(nameof(Output), "IMAGE", null);
+        Input = CreateInput<Surface>(nameof(Input), "IMAGE", null);
+        Filter = CreateInput<Filter>(nameof(Filter), "FILTER", null);
+    }
+    
+    protected override Surface? OnExecute(RenderingContext context)
+    {
+        if (Input.Value is not { } input)
+        {
+            return null;
+        }
+        
+        _paint.SetFilters(Filter.Value);
+
+        var workingSurface = new Surface(input.Size);
+        
+        workingSurface.DrawingSurface.Canvas.DrawSurface(input.DrawingSurface, 0, 0, _paint);
+
+        Output.Value = workingSurface;
+        return workingSurface;
+    }
+
+    public override Node CreateCopy() => new ApplyFilterNode();
+}

+ 39 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FilterNode.cs

@@ -0,0 +1,39 @@
+using PixiEditor.ChangeableDocument.Rendering;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+
+namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+
+public abstract class FilterNode : Node
+{
+    public OutputProperty<Filter> Output { get; }
+    
+    public InputProperty<Filter?> Input { get; }
+    
+    public FilterNode()
+    {
+        Output = CreateOutput<Filter>(nameof(Output), "FILTERS", null);
+        Input = CreateInput<Filter>(nameof(Input), "PREVIOUS", null);
+    }
+    
+    protected override Surface? OnExecute(RenderingContext context)
+    {
+        var colorFilter = GetColorFilter();
+        var imageFilter = GetImageFilter();
+
+        if (colorFilter == null && imageFilter == null)
+        {
+            Output.Value = Input.Value;
+            return null;
+        }
+
+        var filter = Input.Value;
+
+        Output.Value = filter == null ? new Filter(colorFilter, imageFilter) : filter.Add(colorFilter, imageFilter);
+        
+        return null;
+    }
+
+    protected virtual ColorFilter? GetColorFilter() => null;
+    
+    protected virtual ImageFilter? GetImageFilter() => null;
+}

+ 4 - 23
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/KernelNode.cs

@@ -6,14 +6,10 @@ using PixiEditor.Numerics;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 
-public class KernelFilterNode : Node
+public class KernelFilterNode : FilterNode
 {
     private readonly Paint _paint = new();
     
-    public OutputProperty<Surface> Transformed { get; }
-    
-    public InputProperty<Surface?> Image { get; }
-    
     public InputProperty<Kernel> Kernel { get; }
     
     public InputProperty<double> Gain { get; }
@@ -27,8 +23,6 @@ public class KernelFilterNode : Node
     public override string DisplayName { get; set; } = "KERNEL_FILTER_NODE";
     public KernelFilterNode()
     {
-        Transformed = CreateOutput<Surface>(nameof(Transformed), "TRANSFORMED", null);
-        Image = CreateInput<Surface>(nameof(Image), "IMAGE", null);
         Kernel = CreateInput(nameof(Kernel), "KERNEL", Numerics.Kernel.Identity(3, 3));
         Gain = CreateInput(nameof(Gain), "GAIN", 1d);
         Bias = CreateInput(nameof(Bias), "BIAS", 0d);
@@ -38,27 +32,14 @@ public class KernelFilterNode : Node
 
     protected override string NodeUniqueName => "KernelFilter";
 
-    protected override Surface? OnExecute(RenderingContext context)
+    protected override ImageFilter? GetImageFilter()
     {
-        var input = Image.Value;
-
-        if (input == null)
-            return null;
-        
         var kernel = Kernel.Value;
-        var workingSurface = new Surface(input.Size);
-
-        var kernelOffset = new VecI(kernel.RadiusX, kernel.RadiusY);
-        using var imageFilter = ImageFilter.CreateMatrixConvolution(kernel, (float)Gain.Value, (float)Bias.Value, kernelOffset, Tile.Value, OnAlpha.Value);
-
-        _paint.ImageFilter = imageFilter;
-        workingSurface.DrawingSurface.Canvas.DrawSurface(Image.Value.DrawingSurface, 0, 0, _paint);
         
-        Transformed.Value = workingSurface;
+        var kernelOffset = new VecI(kernel.RadiusX, kernel.RadiusY);
         
-        return workingSurface;
+        return ImageFilter.CreateMatrixConvolution(kernel, (float)Gain.Value, (float)Bias.Value, kernelOffset, Tile.Value, OnAlpha.Value);
     }
 
-
     public override Node CreateCopy() => new KernelFilterNode();
 }

+ 13 - 0
src/PixiEditor.ChangeableDocument/Helpers/PaintHelper.cs

@@ -0,0 +1,13 @@
+using PixiEditor.ChangeableDocument.Changeables.Graph;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+
+namespace PixiEditor.ChangeableDocument.Helpers;
+
+internal static class PaintHelper
+{
+    public static void SetFilters(this Paint paint, Filter? filter)
+    {
+        paint.ColorFilter = filter?.ColorFilter;
+        paint.ImageFilter = filter?.ImageFilter;
+    }
+}