Jump to content

TR's Str8Edge Tool V1.1


Recommended Posts

TR's Str8Edge Tool V1.1


Smooths out jagged edges on a Cut-Out.


(For those of use who's hands are not that steady)


 


Version 1.1 Updated for Paint.net 4.0


 


 


Menu:


Effects->Object


 


 


Str8Edge.PNG?raw=1


 


Deselect before using.


 


YouTube Example



 


Composite of tiger done with Lasso and Str8Edge tool. No Edge Feathering!!!


(Minimal Cleanup - Hand drawn  whiskers)


 


Hand Selected Tiger


Str8EdgeTiger.png?raw=1


 


The Code


Hidden Content:

// Compiler options:  /unsafe /optimize /debug- /target:library /out:"C:\Program Files\Paint.NET\Effects\TRsStr8Edge.dll"

using System;

using System.Text;

using System.Windows;

using System.Reflection;

using System.Windows.Forms;

using PaintDotNet;

using PaintDotNet.Effects;

using PaintDotNet.IndirectUI;

using PaintDotNet.PropertySystem;

using System.Collections.Generic;

using System.Drawing;

using System.Drawing.Text;

using System.Runtime.CompilerServices;

using System.Runtime.InteropServices;

 

[assembly: AssemblyTitle("TRsStr8EdgePlugin")]

[assembly: AssemblyDescription("TRsStr8Edge Plugin for Paint.NET. (Compiled by Code Lab v1.8)")]

[assembly: AssemblyConfiguration("")]

[assembly: AssemblyCompany("TechnoRobbo")]

[assembly: AssemblyProduct("TRsStr8EdgePlugin")]

[assembly: AssemblyCopyright("Copyright © TechnoRobbo")]

[assembly: AssemblyTrademark("")]

[assembly: AssemblyCulture("")]

[assembly: ComVisible(false)]

[assembly: AssemblyVersion("1.1.*")]

 

namespace TRsStr8EdgeEffect

{

    public class PluginSupportInfo : IPluginSupportInfo

    {

        public string Author

        {

            get

            {

                return "TechnoRobbo";

            }

        }

        public string Copyright

        {

            get

            {

                return ((AssemblyCopyrightAttribute)base.GetType().Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false)[0]).Copyright;

            }

        }

 

        public string DisplayName

        {

            get

            {

                return ((AssemblyProductAttribute)base.GetType().Assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false)[0]).Product;

            }

        }

 

        public Version Version

        {

            get

            {

                return base.GetType().Assembly.GetName().Version;

            }

        }

 

        public Uri WebsiteUri

        {

            get

            {

                return new Uri("http://www.technorobbo.com");

            }

        }

    }

 

    [PluginSupportInfo(typeof(PluginSupportInfo), DisplayName = "TRsStr8Edge")]

    public class TRsStr8EdgeEffectPlugin : PropertyBasedEffect

    {

        public static string StaticName

        {

            get

            {

                return "TR's Str8 Edge";

            }

        }

 

        public static Image StaticIcon

        {

            get

            {

                return null;

            }

        }

 

        public TRsStr8EdgeEffectPlugin()

            : base(StaticName, StaticIcon, "Object", EffectFlags.Configurable)

        {

        }

 

        public enum PropertyNames

        {

            Amount1

        }

 

 

        protected override PropertyCollection OnCreatePropertyCollection()

        {

            List<Property> props = new List<Property>();

 

            props.Add(new Int32Property(PropertyNames.Amount1, 1, 1, 20));

 

            return new PropertyCollection(props);

        }

 

        protected override ControlInfo OnCreateConfigUI(PropertyCollection props)

        {

            ControlInfo configUI = CreateDefaultConfigUI(props);

 

            configUI.SetPropertyControlValue(PropertyNames.Amount1, ControlInfoPropertyNames.DisplayName, "Amount");

 

            return configUI;

        }

 

        bool noskip = true;

        protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs)

        {

            this.Amount1 = newToken.GetProperty<Int32Property>(PropertyNames.Amount1).Value;

            noskip = true;

            base.OnSetRenderInfo(newToken, dstArgs, srcArgs);

        }

 

 

        protected override void OnCustomizeConfigUIWindowProperties(PropertyCollection props)

        {

            // Change the effect's window title

            props[ControlInfoPropertyNames.WindowTitle].Value = "TR's Str8 Edge - V 1.1";

            base.OnCustomizeConfigUIWindowProperties(props);

        }

 

        protected override unsafe void OnRender(Rectangle[] rois, int startIndex, int length)

        {

            if (length == 0) return;

            for (int i = startIndex; i < startIndex + length; ++i)

            {

                Render(DstArgs.Surface, SrcArgs.Surface, rois);

            }

        }

 

        #region User Entered Code

        // Submenu: Object

        // Name: TR's Str8 Edge 

        // Title: TR's Str8 Edge - V 1.1 

        // Author: TechnoRobbo

        // URL: http://www.technorobbo.com

        #region UICode

        int Amount1 = 1; // [1,20] Amount

        #endregion

 

        

        void Render(Surface dst, Surface src, Rectangle rect)

        {

            if (noskip)

            {

                Rectangle sel = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

                dst.CopySurface(src, sel.Location, sel);

                noskip = false;

                try

                {

                    ColorBgra CP = new ColorBgra();

                    int[] offx = { -1, 0, 1, -1, 1, -1, 0, 1 };

                    int[] offy = { -1, -1, -1, 0, 0, 1, 1, 1 };

                    byte[,] agrid = new byte[sel.Width, sel.Height];

                    byte[,] bgrid = new byte[sel.Width, sel.Height];

                    //=================================================

                    for (int oy = sel.Top; oy < sel.Bottom; oy++)

                    {

                        for (int ox = sel.Left; ox < sel.Right; ox++)

                        {

                            CP = src.GetBilinearSampleClamped(ox, oy);

                            bgrid[ox, oy] = (byte)((CP.A == 0) ? 0 : 255);

                        }

                    }

                    //---------------------------------------------------  

                    for (int z = 0; z < Amount1; z++)

                    {

                        Array.Copy(bgrid, agrid, agrid.Length);

                        for (int y = sel.Top; y < sel.Bottom; y++)

                        {

                            for (int x = sel.Left; x < sel.Right; x++)

                            {

 

                                if (agrid[x, y] != 0)

                                {

 

                                    int Threshold = 255;

                                    int Sigma = 0;

                                    for (int i = 0; i < 8; i++)

                                    {

                                        int nx = Int32Util.Clamp(offx + x, 0, sel.Width - 1);

                                        int ny = Int32Util.Clamp(offy + y, 0, sel.Height - 1);

                                        Threshold = Math.Min(agrid[nx, ny], Threshold);

                                        Sigma += agrid[nx, ny];

                                    }

 

                                    if (Threshold == 0)

                                    {

 

                                        CP = src.GetBilinearSample(x, y);

                                        if (Sigma >= 1275)

                                        {

                                            CP.A = 255;

                                        }

                                        else

                                        {

                                            CP.A = 0;

                                            bgrid[x, y] = 0;

                                        }

                                        dst[x, y] = CP;

                                    }

                                } //if

                            } //x

                        } //y

                    }

                }

                catch (Exception e) { }

            }

            else

            {

                ColorBgra CP = dst[0, 0];

                dst[0, 0] = CP;

            }

 

        }

        #endregion

    }

}

 

 



TRsStr8Edge.zip

Edited by TechnoRobbo
  • Upvote 3

Go out there and be amazing. Have Fun, TR
TRsSig.png?raw=1
Some Pretty Pictures Some Cool Plugins

Link to comment
Share on other sites

How it Works


 


The tool examines each pixel twice. First it looks for the tell-tale pattern of an edge.


Then it looks for the tell-tale pattern of a straight edge.


 


An edge is found when an adjacent pixel being transparent.


a straight edge is found when the sum of the adjacent pixels alpha is equal or higher than 1275!


If the pixel is not partof a straight edge - it's removed.


 


Why 1275? a Opaque pixel has a Alpha value of 255. 1275 is 255 times 5.


 


Str8EdgeHow.PNG?raw=1


The tool allows for 20 consecutive passes.


Edited by TechnoRobbo
  • Upvote 1

Go out there and be amazing. Have Fun, TR
TRsSig.png?raw=1
Some Pretty Pictures Some Cool Plugins

Link to comment
Share on other sites

  • 2 months later...
  • 4 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...