Sign in to follow this  
TechnoRobbo

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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Not only a fab new plugin but a good explanation for how it works. So is this similar to Feather & the Old Feather?

 

I was amazed at your mouse control with the lasso tool :P

 

Thankies once again for another beaut plugin!

Share this post


Link to post
Share on other sites

No it's not a feather. There's no feathering at all. It rejects pixels that don't conform to a straight edge definition.

 

Actually I don't have good lasso control the Str8Edge tool corrected my coffee-fueled mess.

Share this post


Link to post
Share on other sites

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.

Sign in to follow this