Bladeren bron

Added magic wand tolerance

flabbet 9 maanden geleden
bovenliggende
commit
801e63e686

+ 17 - 2
src/ChunkyImageLib/DataHolders/ColorBounds.cs

@@ -21,13 +21,17 @@ public struct ColorBounds
 
     public float UpperA { get; set; }
 
-    public ColorBounds(Color color)
+    public ColorBounds(Color color, double tolerance = 0)
     {
         static (float lower, float upper) FindInclusiveBoundaryPremul(byte channel, float alpha)
         {
             float subHalf = channel > 0 ? channel - .5f : channel;
             float addHalf = channel < 255 ? channel + .5f : channel;
-            return (subHalf * alpha / 255f, addHalf * alpha / 255f);
+            
+            var lower = subHalf * alpha / 255f;
+            var upper = addHalf * alpha / 255f;
+            
+            return (lower, upper);
         }
 
         static (float lower, float upper) FindInclusiveBoundary(byte channel)
@@ -40,9 +44,20 @@ public struct ColorBounds
         float a = color.A / 255f;
 
         (LowerR, UpperR) = FindInclusiveBoundaryPremul(color.R, a);
+        LowerR -= (float)tolerance;
+        UpperR += (float)tolerance;
+        
         (LowerG, UpperG) = FindInclusiveBoundaryPremul(color.G, a);
+        LowerG -= (float)tolerance;
+        UpperG += (float)tolerance;
+        
         (LowerB, UpperB) = FindInclusiveBoundaryPremul(color.B, a);
+        LowerB -= (float)tolerance;
+        UpperB += (float)tolerance;
+        
         (LowerA, UpperA) = FindInclusiveBoundary(color.A);
+        LowerA -= (float)tolerance;
+        UpperA += (float)tolerance;
     }
 
     [MethodImpl(MethodImplOptions.AggressiveInlining)]

+ 4 - 1
src/PixiEditor.ChangeableDocument/Changes/Selection/MagicWand/MagicWandHelper.cs

@@ -108,10 +108,13 @@ internal class MagicWandHelper
     }
 
     public static VectorPath DoMagicWandFloodFill(VecI startingPos, HashSet<Guid> membersToFloodFill,
+        double tolerance,
         IReadOnlyDocument document, int frame)
     {
         if (startingPos.X < 0 || startingPos.Y < 0 || startingPos.X >= document.Size.X || startingPos.Y >= document.Size.Y)
             return new VectorPath();
+        
+        tolerance = Math.Clamp(tolerance, 0, 1);
 
         int chunkSize = ChunkResolution.Full.PixelSize();
 
@@ -127,7 +130,7 @@ internal class MagicWandHelper
             static (EmptyChunk _) => Colors.Transparent
         );
 
-        ColorBounds colorRange = new(colorToReplace);
+        ColorBounds colorRange = new(colorToReplace, tolerance);
 
         HashSet<VecI> processedEmptyChunks = new();
 

+ 4 - 2
src/PixiEditor.ChangeableDocument/Changes/Selection/MagicWand/MagicWand_Change.cs

@@ -14,15 +14,17 @@ internal class MagicWand_Change : Change
     private readonly List<Guid> memberGuids;
     private readonly SelectionMode mode;
     private int frame;
+    private double tolerance;
 
     [GenerateMakeChangeAction]
-    public MagicWand_Change(List<Guid> memberGuids, VecI point, SelectionMode mode, int frame)
+    public MagicWand_Change(List<Guid> memberGuids, VecI point, SelectionMode mode, double tolerance, int frame)
     {
         path.MoveTo(point);
         this.mode = mode;
         this.memberGuids = memberGuids;
         this.point = point;
         this.frame = frame;
+        this.tolerance = tolerance;
     }
 
     public override bool InitializeAndValidate(Document target)
@@ -41,7 +43,7 @@ internal class MagicWand_Change : Change
                 membersToReference.Add(member.Id);
         });
 
-        path = MagicWandHelper.DoMagicWandFloodFill(point, membersToReference, target, frame);
+        path = MagicWandHelper.DoMagicWandFloodFill(point, membersToReference, tolerance, target, frame);
 
         ignoreInUndo = false;
         return CommonApply(target);

+ 2 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -760,5 +760,6 @@
   "PAINT_TOOLSET": "Painting",
   "HARDNESS_SETTING": "Hardness",
   "SPACING_SETTING": "Spacing",
-  "ANTI_ALIASING_SETTING": "Anti-aliasing"
+  "ANTI_ALIASING_SETTING": "Anti-aliasing",
+  "TOLERANCE_LABEL": "Tolerance"
 }

+ 3 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/MagicWandToolExecutor.cs

@@ -14,6 +14,7 @@ internal class MagicWandToolExecutor : UpdateableChangeExecutor
     private bool drawOnMask;
     private List<Guid> memberGuids;
     private SelectionMode mode;
+    private float tolerance;
 
     public override ExecutionState Start()
     {
@@ -29,8 +30,9 @@ internal class MagicWandToolExecutor : UpdateableChangeExecutor
         if (considerAllLayers)
             memberGuids = document!.StructureHelper.GetAllLayers().Select(x => x.Id).ToList();
         var pos = controller!.LastPixelPosition;
+        tolerance = (float)magicWand.Tolerance;
 
-        internals!.ActionAccumulator.AddActions(new MagicWand_Action(memberGuids, pos, mode, document!.AnimationHandler.ActiveFrameBindable));
+        internals!.ActionAccumulator.AddActions(new MagicWand_Action(memberGuids, pos, mode, tolerance, document!.AnimationHandler.ActiveFrameBindable));
 
         return ExecutionState.Success;
     }

+ 1 - 0
src/PixiEditor/Models/Handlers/Tools/IMagicWandToolHandler.cs

@@ -7,4 +7,5 @@ internal interface IMagicWandToolHandler : IToolHandler
 {
     public SelectionMode SelectMode { get; }
     public DocumentScope DocumentScope { get; }
+    public float Tolerance { get; }
 }

+ 3 - 0
src/PixiEditor/ViewModels/Tools/Tools/MagicWandToolViewModel.cs

@@ -28,6 +28,9 @@ internal class MagicWandToolViewModel : ToolViewModel, IMagicWandToolHandler
     [Settings.Enum("SCOPE_LABEL")]
     public DocumentScope DocumentScope => GetValue<DocumentScope>();
 
+    [Settings.Percent("TOLERANCE_LABEL", ExposedByDefault = false)]
+    public float Tolerance => GetValue<float>();
+
     public override string Icon => PixiPerfectIcons.MagicWand;
 
     public MagicWandToolViewModel()