Ossobuko

Please debug my plugin - Pixel Gradient Outline

6 posts in this topic

Posted (edited)

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
0

Share this post


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

1

Share this post


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

0

Share this post


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

0

Share this post


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

0

Share this post


Link to post
Share on other sites

Can't you do what you want with the built-in effect Effects > Distort > Frosted Glass ?

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now