Jump to content

Shaped gradient - my first plugin


n d

Recommended Posts

I'm very new to C# - I only started learning it a few days ago.

So here's the first plugin I managed to make - it creates a gradient in the shape of the selection.

It works fine, but it's a bit slow... can someone help me optimize the code?

Download plugin from this link: Shaped Gradient 1.1

Here's sample output:

shapesample.png

Here's the source:

#region UICode
ColorBgra Amount1 = ColorBgra.FromBgr(0,0,0); // Center colour
ColorBgra Amount2 = ColorBgra.FromBgr(0,0,0); // Edge colour
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
// Delete any of these lines you don't need
Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
int MaxX = ((selection.Right - selection.Left) / 2);
int MaxY = ((selection.Bottom - selection.Top) / 2);	
PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);


int CenterX = MaxX+selection.Left;
int CenterY = MaxY+selection.Top;

int MaxDist;
double disd = System.Math.Sqrt ( (MaxX*MaxX)+(MaxY*MaxY));
MaxDist = (int)disd;
// maximum distance is MaxDist;


// render loop:

double dx,dy;
double cDist;
int eDist;
int loopnum;

double cAngle;
double nDist;

int cAmount, eAmount;

ColorBgra CurrentPixel;
for (int y = rect.Top; y < rect.Bottom; y++)
{
	for (int x = rect.Left; x < rect.Right; x++)
	{

// get angle to center:
dx = x - CenterX; dy = y - CenterY;
cAngle = System.Math.Atan2(dx,dy);

// get distance to center:
cDist = System.Math.Sqrt((dx*dx)+(dy*dy));

// distance loop:	

loopnum = MaxDist - (int)cDist; eDist=loopnum;
for (int a=0; a<loopnum; a++) {
	double xx,yy;
	int xa,ya;
	xx = System.Math.Sin(cAngle)*(double)a;
	yy = System.Math.Cos(cAngle)*(double)a;
	xa = (int)xx + x;
	ya = (int)yy + y;

	if (!selectionRegion.IsVisible(xa,ya)) {eDist=a; a=loopnum;}

}

nDist = (cDist/(cDist+(double)eDist))*255d;
eAmount = (int)nDist;
cAmount = 255-eAmount;


// pixel draw code

	int r = ((Amount1.R * cAmount)/255) + ((Amount2.R * eAmount)/255);
	int g = ((Amount1.G * cAmount)/255) + ((Amount2.G * eAmount)/255);
	int b = ((Amount1.B * cAmount)/255) + ((Amount2.B * eAmount)/255);

	CurrentPixel = ColorBgra.FromBgra((byte)b,(byte)g,(byte)r,(byte)255);
//	CurrentPixel.R = ((Amount1.R * (byte)cAmount)/(byte)255) + ((Amount2.R * (byte)eAmount)/(byte)255);
//	CurrentPixel.G = ((Amount1.G * (byte)cAmount)/255) + ((Amount2.G * (byte)eAmount)/255);
//	CurrentPixel.B = ((Amount1.B * (byte)cAmount)/255) + ((Amount2.B * (byte)eAmount)/255);

	dst[x,y] = CurrentPixel;
	}
}
}



Edited by n d

ndeee2.png

Link to comment
Share on other sites

It is fast on my machine-XP-SP3. Lucky I am :)

And the result is fabulous, this will be one of my favorite, well done n d .

I used it on one layer of cloud and got this:

th_cloudgrad.png

Thanks for the great plugin.

Well thanks for the kind words... I appreciate it. Can I ask what kind of computer you have? Because on my 1.8ghz core2d it takes like 5-10 seconds to render a 800x800 selection...

I came up with the program algorithm on my own... basically what it does is, it gets the angle between the current pixel and the center of selection... Then it moves pixel-by-pixel in that angle to the other direction (away from center) and checks on each pixel if it's selected, and when it finds a pixel that is not selected it assumes it to be edge of selection. Then it calculates the distance to center & distance to edge, and calculates the colour based on the ratio of the distances.

I'm wondering if something like this might work better: before the render loop, it would scan a full circle to obtain the edge of selection for each angle, then in the render loop just get the angle vs center for each pixel and retrieve the edge distance from an array...

Anyway, it would be extra nice if some of the more experienced coders could give some hints&tips on this. I'm satisfied with what the effect does, I'd just like it to do it a bit faster ;)

ndeee2.png

Link to comment
Share on other sites

This is going to be a promising plug-in. My only suggestion is to add an anti-alias option, and I'm basing it on an observation of the images you have posted. I haven't downloaded it or played with it yet. It should work pretty fast on my Win7 laptop with a i5 core and 6 GB of RAM.

Officially retired from this forum. Have a nice day.

Link to comment
Share on other sites

This is going to be a promising plug-in. My only suggestion is to add an anti-alias option, and I'm basing it on an observation of the images you have posted. I haven't downloaded it or played with it yet. It should work pretty fast on my Win7 laptop with a i5 core and 6 GB of RAM.

Adding anti-alias may be problematic since the plugin works on a selection. At least, I have no idea how to do it...:/

ndeee2.png

Link to comment
Share on other sites

Adding anti-alias may be problematic since the plugin works on a selection. At least, I have no idea how to do it...:/

Take a look at some of MadJik's and BoltBait's plug-ins. I am sure that some of their source code includes the code to how to add anti-aliasing option. Don't get discouraged, mate, I really like the possibilities of this plug-in.

Officially retired from this forum. Have a nice day.

Link to comment
Share on other sites

What I mean is, when you use a plugin on a selection, the outline of the selection is always going to leave a jagged edge, the plugin cannot affect pixels outside the selection... you can see this same phenomenon on other selection plugins like bevel selection, outline selection etc.

I could add a gaussian blur function to the plugin, but then, you can already do a gaussian blur after using the plugin, so it seems rather redundant to me...

Anyway, here's some things you can do with this plugin + some other common plugins... looking at the images, you can probably guess which other plugins were used ;)

hexagonr.png

heh.png

ruusu.png

  • Upvote 1

ndeee2.png

Link to comment
Share on other sites

What I mean is, when you use a plugin on a selection, the outline of the selection is always going to leave a jagged edge, the plugin cannot affect pixels outside the selection... you can see this same phenomenon on other selection plugins like bevel selection, outline selection etc.

Perhaps the code/concept of Feather Selection as a

first step before the gradient part of the effect?

I don't code, so don't know whether this is feasible.

Link to comment
Share on other sites

1. Render clouds

2. magic wand anywhere on the clouds

3. new layer & shaped gradient

4. invert selection, shaped gradient

easy.

although, if you're concerned with aliasing, you'd better put the first & second shaped gradients on separate layers, then run object feather on radius 1 on each of them.

Edited by n d

ndeee2.png

Link to comment
Share on other sites

Perhaps the code/concept of Feather Selection as a

first step before the gradient part of the effect?

I don't code, so don't know whether this is feasible.

It would be feasible, code-wise, but I don't see the point. If you want to, you can run feather selection yourself right after using this.

ndeee2.png

Link to comment
Share on other sites

Sorry for the triple post... but here's a sneak preview of Shaped Gradient's little brother, 3d trail. Actually, I modified it from the SG code, so perhaps it's more a nephew than a brother ;)

Unlike shaped gradient, for this plugin I do intend to add anti-aliasing at some point.

This is an object-plugin, so you will need a transparent layer with some text/graphics on it before applying 3d trail. Otherwise it won't do anything.

3d Trail

it does this:

trailsample.png

Like I said, this one still needs work...

Edited by n d

ndeee2.png

Link to comment
Share on other sites

It would be feasible, code-wise, but I don't see the point. If you want to, you can run feather selection yourself right after using this.

I was thinking in terms of the jaggies produced within the gradient,

as inside the letters E and X in the word TEXT in the first post.

Running Feather won't change those.

However, those may not be a product of the selection edge anyway.

Link to comment
Share on other sites

I was thinking in terms of the jaggies produced within the gradient,

as inside the letters E and X in the word TEXT in the first post.

Running Feather won't change those.

However, those may not be a product of the selection edge anyway.

Right, I see what you mean. At this point I'm not totally sure how to fix it though. I would guess a gaussian function or a convolution filter would need to be applied, and this must be done after the gradient has been rendered... I need to look into this.

ndeee2.png

Link to comment
Share on other sites

:roll: sorry this might be a dumb dumb question but I've not been around for awhile. rar files? how do I extract the .dll to put into my effects file?

I tried using the source to build a dll but received an error message (sorry didn't write it down) but it was basically telling me there was an error on a certain line.

ciao OMA

Link to comment
Share on other sites

:roll: sorry this might be a dumb dumb question but I've not been around for awhile. rar files? how do I extract the .dll to put into my effects file?

I tried using the source to build a dll but received an error message (sorry didn't write it down) but it was basically telling me there was an error on a certain line.

ciao OMA

Google Winrar, install winrar on your computer, when installation is done you can extract .rars by double-clicking them.

ndeee2.png

Link to comment
Share on other sites

Why not just pack it in .zip? Windows comes with a zip extractor.

I guess I'm just used to using rar. I would upload it unpacked but fileden doesn't allow .dll files.

Anyway .rar files are really common - 90% of the pdn plugins I've downloaded were packed as .rars so getting winrar will benefit you in more ways than just using my plugin ;)

ndeee2.png

Link to comment
Share on other sites

Hm, yeah my bad. I was thinking of some other site with some other thing I've downloaded ...

Anyway, as for anti-aliasing for the plugin... I'm afraid I'm completely at a loss as to how to call a gaussian blur effect after the dst surface has already been filled. After reading some codelab documentation it seems I would have to create a new Surface object in order for this to work, however, I can't seem to figure out how to initiate it...

I tried

Surface dst2 = new Surface(); // but it requires parameters so then I tried

Surface dst2 = new Surface(src.Size); // then codelab complains, "System.Windows.Size is referenced in an assembly that is not referenced..." and I'm not even totally sure what this means...

Anyway, I'm too tired to figure this out at the moment - it's almost 6am, perhaps if I go to sleep now someone will have solved this problem for me... ;)

ndeee2.png

Link to comment
Share on other sites

Thanks APShredder. But now that I think of it, I highly doubt if applying gaussian blur is going to work...

See, if paint.net divides the selection in ROI:s and then calls the render method for each ROI, then it is impossible to call the gaussian blur so that the whole image would already be rendered. And this means the gaussian blur would also take some transparent pixels (or pixels of the old image) and this would mess it up...

So I've got to think of something else.

Pyrochild, what do you have against RAR?

ndeee2.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...