Jump to content

Please debug my plugin - Pixel Gradient Outline


Ossobuko

Recommended Posts

Hello, I am a complete newbie. Sorry in advance.

I am trying to develop a plugin for my personal use. But it seems there is a problem and I cannot understand why that happens. You can find the source code and example of the problem in the attached files.

 

Here is steps to reproduce the problem:

1. open a transparent, empty image.

2. draw a shape to it. make sure it doesn't cover everything.

3. Effects>Object>Pixel Gradient Outline

4. Play with the dials until it stops working.

 

At first everything works fine (like in the first picture), until the point of no return and it just starts to outline the object (look at the second picture).

I am attaching dll file with source code and example pictures.

 

// Name: Pixel Gradient Outline
// Submenu: Object
// Author: Ossobuko
// Title: Pixel Gradient Outline
// Version: 1
// Desc:
// Keywords:
// URL:
// Help:
#region UICode
IntSliderControl Amount1 = 10; //[1,200]Radius
#endregion

static Random rnd = new Random();

void Render(Surface dst, Surface src, Rectangle rect)
{
    // Delete any of these lines you don't need
    ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
    Surface output = blur(src, rect, Amount1);
    
    ColorBgra inputPixel, outputPixel;
    for (int y = rect.Top; y < rect.Bottom; y++) {
        if (IsCancelRequested) return;
        for (int x = rect.Left; x < rect.Right; x++) {
            // original image
            inputPixel = src[x,y];
            // blurred original image
            outputPixel = output[x,y];
            if ((inputPixel.A == 0) && (outputPixel.A != 0) && (rnd.Next(0,256) < outputPixel.A)) {
                dst[x,y] = PrimaryColor;
            } else dst[x,y] = inputPixel;
        }
    }
}

Surface blur(Surface src, Rectangle rect, float radius) {
    Surface dst = src.Clone();
    for(float a=radius; a>0; a--) {
        Surface current = dst.Clone();
        outline(current, src, rect, (int)a,ColorBgra.Black);
        
        for (int y = rect.Top; y < rect.Bottom; y++) {
            for (int x = rect.Left; x < rect.Right; x++) {
                if ((src[x,y].A == 0) && (current[x,y].A != 0)) {
                    ColorBgra color = new ColorBgra();
                    color.R = color.G = color.B = 0;
                    color.A = (byte) (int)(255*((radius-a)/radius));
                    dst[x,y] = color;
                } 
            }
        }
    }
    return dst;
}

void outline(Surface dst, Surface src, Rectangle rect, int radius, ColorBgra color) {
    // Setup for calling Gaussian Blur
    GaussianBlurEffect blurEffect = new GaussianBlurEffect();
    PropertyCollection bProps = blurEffect.CreatePropertyCollection();  
    PropertyBasedEffectConfigToken bParameters = new PropertyBasedEffectConfigToken(bProps);
    bParameters.SetPropertyValue(GaussianBlurEffect.PropertyNames.Radius, radius); // fix
    blurEffect.SetRenderInfo(bParameters, new RenderArgs(dst), new RenderArgs(src));
    // Call Gaussian Blur
    blurEffect.Render(new Rectangle[1] {rect},0,1);
    
    ColorBgra inputPixel, outputPixel;
    for (int y = rect.Top; y < rect.Bottom; y++) {
        for (int x = rect.Left; x < rect.Right; x++) {
            // original image
            inputPixel = src[x,y];
            // blurred original image
            outputPixel = dst[x,y];
            if ((inputPixel.A == 0) && (outputPixel.A != 0)) {
                dst[x,y] = color;
            } else dst[x,y] = inputPixel;
        }
    }
}

 

MyScript.cs

Sketch1.png

Sketch2.png

Pixel Gradient Outline - Pain.net.dll

Edited by Ossobuko
Link to comment
Share on other sites

First...

 

44 minutes ago, Ossobuko said:

static Random rnd = new Random();

 

 

...Don't do this.  Random is not thread safe.

 

Better to add a Reseed button:

 

#region UICode
IntSliderControl Amount1 = 10; //[1,200]Radius
ReseedButtonControl Amount2 = 0; // [255] Reseed
#endregion

Access random numbers this way:

 

(byte)RandomNumber.Next(256);

etc.

  • Upvote 1
Link to comment
Share on other sites

Second, if you want help with your algorithm, post 2 pictures: (1) a picture of what your canvas looks like before running your effect, and (2) a picture of what you want your result to be.  I don't care how you do it, just make a mock up.

 

Your code is a complete mess.  We'll need to start from scratch.

Link to comment
Share on other sites

Not to mention horribly inefficient.

 

With all those loops, you're:

1) creating a ton of Surface objects

2) calling the Gaussian Blur effect a ton of times.

 

Both are resource intensive.

 

Your plugin probably could be debugged, but I agree with BoltBait; the whole thing needs to be rewritten.

We can help you with this, if you're interested.

(September 25th, 2023)  Sorry about any broken images in my posts. I am aware of the issue.

bp-sig.png
My Gallery  |  My Plugin Pack

Layman's Guide to CodeLab

Link to comment
Share on other sites

Thanks for the help and ideas. Thank you very much for your quick response. This is really a great community.

 

Yes, I know the code is horrible. It is meant to be used personally and on very small areas, so it actually works well enough (and not too bad).

 

I solved the problem by removing random and using:

RandomNumber.Next(256)

Thanks BoltBait.

Untitled.png

Link to comment
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.

×
×
  • Create New...