diff options
author | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-03-31 22:44:05 +0300 |
---|---|---|
committer | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-03-31 22:44:05 +0300 |
commit | 5a1082da96d2565a0f5c155dd9ccd621eff86026 (patch) | |
tree | 6c8cfc9fd5fc56dca774d5d5de5182350c08f700 /UVtools.ScriptSample | |
parent | f683d3ccc8ee60ded9d5964d48233b14d68c0862 (diff) |
Add script sample
Diffstat (limited to 'UVtools.ScriptSample')
-rw-r--r-- | UVtools.ScriptSample/ScriptSample.cs | 131 | ||||
-rw-r--r-- | UVtools.ScriptSample/UVtools.ScriptSample.csproj | 11 |
2 files changed, 142 insertions, 0 deletions
diff --git a/UVtools.ScriptSample/ScriptSample.cs b/UVtools.ScriptSample/ScriptSample.cs new file mode 100644 index 0000000..83f5ca0 --- /dev/null +++ b/UVtools.ScriptSample/ScriptSample.cs @@ -0,0 +1,131 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +using System; +using System.Drawing; +using System.Text; +using System.Threading.Tasks; +using UVtools.Core.Scripting; +using Emgu.CV; +using Emgu.CV.CvEnum; + +namespace UVtools.ScriptSample +{ + public class ScriptSample : ScriptGlobals + { + ScriptNumericalInput<ushort> InsetMarginFromEdge = new() + { + Label = "Inset from edge", + ToolTip = "Margin in pixels to inset from object edge", + Unit = "px", + Minimum = 1, + Maximum = ushort.MaxValue, + Increment = 1, + Value = 20 + }; + + ScriptNumericalInput<ushort> InsetThickness = new() + { + Label = "Inset line thickness", + ToolTip = "Inset line thickness in pixels", + Unit = "px", + Minimum = 1, + Maximum = ushort.MaxValue, + Increment = 1, + Value = 10 + }; + + /// <summary> + /// Set configurations here, this function trigger just after load a script + /// </summary> + public void ScriptInit() + { + Script.Name = "Inset"; + Script.Description = "Perform a black inset around objects"; + Script.Author = "Tiago Conceição"; + Script.Version = new Version(0, 1); + Script.Inputs.AddRange(new[] + { + InsetMarginFromEdge, + InsetThickness + }); + } + + /// <summary> + /// Validate your user inputs here, this function trigger when user click on execute + /// </summary> + /// <returns>A error message, empty or null if validation passes.</returns> + public string ScriptValidate() + { + StringBuilder sb = new(); + + if (InsetMarginFromEdge.Value < InsetMarginFromEdge.Minimum) + { + sb.AppendLine($"Inset edge margin must be at least {InsetMarginFromEdge.Minimum}{InsetMarginFromEdge.Unit}"); + } + if (InsetThickness.Value < InsetThickness.Minimum) + { + sb.AppendLine($"Inset thickness must be at least {InsetThickness.Minimum}{InsetThickness.Unit}"); + } + + return sb.ToString(); + } + + /// <summary> + /// Execute the script, this function trigger when when user click on execute and validation passes + /// </summary> + /// <returns>True if executes successfully to the end, otherwise false.</returns> + public bool ScriptExecute() + { + var anchor = new Point(-1, -1); // Kernel anchor, -1, -1 = center + var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor); // Rectangle 3x3 kernel + Progress.Reset("Inset layers", Operation.LayerRangeCount); // Sets the progress name and number of items to process + + // Loop user selected layers in parallel, this will put each core of CPU working here on parallel + Parallel.For(Operation.LayerIndexStart, Operation.LayerIndexEnd, layerIndex => + { + if (Progress.Token.IsCancellationRequested) return; // Abort operation, user requested cancellation + + var layer = SlicerFile[layerIndex]; // Unpack and expose layer variable for easier use + using var mat = layer.LayerMat; // Gets this layer mat/image + var original = mat.Clone(); // Keep a original mat copy + using var erodeMat = new Mat(); // Creates a temporary mat for the eroded image + using var wallMat = new Mat(); // Creates a temporary mat for the wall image + + var target = Operation.GetRoiOrDefault(mat); // Get ROI from mat if user selected an region + + // Erode original image by InsetMarginFromEdge pixels, so we get the offset margin from image and put new image on erodeMat + CvInvoke.Erode(target, erodeMat, kernel, anchor, InsetMarginFromEdge.Value, BorderType.Reflect101, default); + + // Now erode the eroded image with InsetThickness pixels, so we get the original-margin-thickness image and put the new image on wallMat + CvInvoke.Erode(erodeMat, wallMat, kernel, anchor, InsetThickness.Value, BorderType.Reflect101, default); + + // Subtract walls image from eroded image, so we get only the inset line pixels in white and put back into wallMat + CvInvoke.Subtract(erodeMat, wallMat, wallMat); + + // Invert pixels of wallMat so the whites will become black and blacks whites + CvInvoke.BitwiseNot(wallMat, wallMat); + + // Bitwise And original image with the modified image and put back into mat + // This will keep only the pixels that are positive in both mat's, so mat[n] & wallMat[n] must both have a positive pixel value (> 0) + CvInvoke.BitwiseAnd(target, wallMat, target); + + // Apply the results only to the selected masked area, if user selected one + Operation.ApplyMask(original, target); + + // Set current layer image with the modified mat we just manipulated + layer.LayerMat = mat; + + // Increment progress bar by 1 + Progress.LockAndIncrement(); + }); + + return true; + } + } +} diff --git a/UVtools.ScriptSample/UVtools.ScriptSample.csproj b/UVtools.ScriptSample/UVtools.ScriptSample.csproj new file mode 100644 index 0000000..d2db2bd --- /dev/null +++ b/UVtools.ScriptSample/UVtools.ScriptSample.csproj @@ -0,0 +1,11 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net5.0</TargetFramework> + </PropertyGroup> + + <ItemGroup> + <ProjectReference Include="..\UVtools.Core\UVtools.Core.csproj" /> + </ItemGroup> + +</Project> |