Rick Brewster

CodeLab v2.24 (for advanced users) Released August 31, 2017

Recommended Posts

Hmmm... wonder if I could set it up to support some type of UI creation... ;)

That's actually something we're hoping to make a lot simpler in a future release of Paint.NET. What we're seeing is that 99.9% of effect plugins just need to specify a few input parameters and are fine with having some default UI associated with them.

I've actually been experimenting with some code for creating an HD Photo plugin. I've not had enough time to really bake it properly, but the notion of having a more declarative model for creating a configuration UI is proving to be a very good way to do things. For example, the following code defines the properties that configure the HD Photo codec, along with default, minimum, and maximum values for each:

            List properties = new List();

           properties.Add(new ScalarProperty(PropertyNames.AlphaDataDiscardLevel, 1, 0, 4));
           properties.Add(new ScalarProperty(PropertyNames.AlphaQualityLevel, 1, 0, 255));
           properties.Add(new BooleanProperty(PropertyNames.CompressedDomainTranscode, true));
           properties.Add(new BooleanProperty(PropertyNames.FlipHorizontal, false));
           properties.Add(new BooleanProperty(PropertyNames.FlipVertical, false));
           properties.Add(new BooleanProperty(PropertyNames.FrequencyOrder, true));
           properties.Add(new ScalarProperty(PropertyNames.HorizontalTileSlices, 0, 0, 4095));
           properties.Add(new BooleanProperty(PropertyNames.IgnoreOverlap, false));
           properties.Add(new ScalarProperty(PropertyNames.ImageDataDiscardLevel, 1, 0, 3));
           properties.Add(new ScalarProperty(PropertyNames.ImageQualityLevel, 0.9f, 0.0f, 1.0f));
           properties.Add(new BooleanProperty(PropertyNames.InterleavedAlpha, false));
           properties.Add(new BooleanProperty(PropertyNames.Lossless, false));
           properties.Add(new ScalarProperty(PropertyNames.OverlapLevel, 1, 0, 2));
           properties.Add(new ScalarProperty(PropertyNames.QualityLevel, 1, 0, 255));
           properties.Add(new EnumProperty(PropertyNames.Rotation, Rotation.Rotate0));
           properties.Add(new ScalarProperty(PropertyNames.SubsamplingLevel, 3, 0, 3));
           properties.Add(new BooleanProperty(PropertyNames.UseCodecOptions, false));
           properties.Add(new ScalarProperty(PropertyNames.VerticalTileSlices, 0, 0, 4095));

...

This actually should work better for Effects. Given a list of these properties, a default UI can be generated on the fly with a simple mapping of property type -> UI handler.

Share this post


Link to post
Share on other sites
EDIT: Hmmm... wonder if I could set it up to support some type of UI creation... ;)

That would be great!

OK, I've added, to CodeLab, the capability to add a user interface (UI) to a script.

    CodeLabUI-full;init:.jpg

This would create a UI similar to this for the effect:

    ColorBalance-full.jpg

Or, by defining only int Amount1=45 with a range of [-180,180] you can build an effect with a UI like this:

    AngleUI-full.jpg

You can also build a 1 or 2 slider UI by simply defining only Amount1 or Amount1 and Amount2.

You can download the new dll here: http://boltbait.googlepages.com/codelab

I have also packaged it up with a bunch of sample cs files that MadJik has modified by adding slider controls to them which you can download from that page. I have also published the complete source code with all of my changes.

Oh, how I wish I'd had this when I first started writing scripts! 8)

EDIT: Fixed the range of the Angle Chooser. Updated the code and source.

Share this post


Link to post
Share on other sites

How to adapt a previous codelab to the new version by the example:

This is the codelab Checker.cs as provided in the zip file.

void Render(Surface dst, Surface src, Rectangle rect)
{
   for(int y = rect.Top; y < rect.Bottom; y++)
   {
       for (int x = rect.Left; x < rect.Right; x++)
       {
           byte c = (byte)(x ^ y);
           dst[x, y] = ColorBgra.FromBgr(c,c,c);
       }
   }
}

In order to make it 'sliderable' we have to decide(or know) what we want the parameter(s) has(ve) to affect. In this case, it will be some kind of zoom effect.

For my example I've decided to change the line

byte c = (byte)(x ^ y);

into

byte c = (byte)(float)((x ^ y) / zoom);

It's just a division, but not to lose precision I make it in a floating format.

Now, I want the zoom between 0.01 and 99.99. The sliders are integers values. So I define a slider from 1 to 9999 that I divide by 100 in the float zoom:

int Amount1 = 100; // [1,9999] Zoom <- you have to respect this model to have a pre-filled slider description and min/dft/max values.

float zoom = Amount1 / 100.0f;

So the default value for Amount1 is 100 and give a zoom=1 (no zoom).

This is the full code modified:

int Amount1 = 100; // [1,9999] Zoom
void Render(Surface dst, Surface src, Rectangle rect)
{
   float zoom = Amount1 / 100.0f;
   for(int y = rect.Top; y < rect.Bottom; y++)
   {
       for (int x = rect.Left; x < rect.Right; x++)
       {
           byte c = (byte)(float)((x ^ y) / zoom);
           dst[x, y] = ColorBgra.FromBgr(c,c,c);
       }
   }
}

Try this codelab and you will see that only amount values multiple of 25 give a regular checker and other values could be surprising!

Then you could adapt some over codelabs...

Enjoy!

Share this post


Link to post
Share on other sites

Thanks MadJik, that's a GREAT example of how to use the new UI creation stuff!

BTW, if you downloaded the new CodeLab DLL between the time I posted my message above and my post right now, you need to download again. I just fixed the range for the Angle chooser from [0,359] to the proper [-180,180]. Sorry for the confusion. (Thanks MadJik for the bug report.)

Let me know if there's anything else.

http://boltbait.googlepages.com/codelab

Share this post


Link to post
Share on other sites

Strange behave:

When I want to create a new DLL and I select a submenu from the listbox and this submenu doesn't exist yet in my menu of effects then the build ends by an error message but in fact it's a success. I close/reopen PDN and the new effect is correctly in the new submenu...

FYI.

Share this post


Link to post
Share on other sites

Very nice. Now I can fill in all those empty icon spaces in my Effects folder...

Er, one thing bugs me though. When I opt to put an effect in Adjustments, it creates a subfolder in Effects called Adjustments. Is this a bug, or are you just locking us out of the real Adjustments folder? <_<

Share this post


Link to post
Share on other sites
Very nice. Now I can fill in all those empty icon spaces in my Effects folder...

Er, one thing bugs me though. When I opt to put an effect in Adjustments, it creates a subfolder in Effects called Adjustments. Is this a bug, or are you just locking us out of the real Adjustments folder? <_>

Heh. I had considered adding the code necessary to allow effects to be put in the actual Adjustments menu, but I didn't. I figured there were very few effects that would go there and it would take a lot more programming on my part... So, in other words, I got lazy.

Tell you what, next time I look at this program, I'll add the code.

Share this post


Link to post
Share on other sites

If my workload EVER lightens up, I simply MUST play with this. Although, I don't know why that's a MUST for me considering my graphic skills are 2 points shy of being below average it is going to be pretty difficult for me to figure out what tool/s would actually benefit me that aren't already present.

Regardless, this is super sweet. I did not know that .NET was capable of doing anything like this.

Share this post


Link to post
Share on other sites
I did not know that .NET was capable of doing anything like this.

Neither did I. Seriously.

Share this post


Link to post
Share on other sites

I have received the task from the teacher to process the image (a black square with white circle in the middle) so that this image has turned to its absent-minded image on a plane which are taking place on some distance from the initial image. Would like to try for these purposes CodeLab, but I do not know, on what algorithm it is necessary to process the initial image. Help me, please.

Share this post


Link to post
Share on other sites

I'm not math studiant... Do your homework and provide me (us) the formulas, and I (we) 'll try to provide you some codelab...

Share this post


Link to post
Share on other sites
I have received the task from the teacher to process the image (a black square with white circle in the middle) so that this image has turned to its absent-minded image on a plane which are taking place on some distance from the initial image. Would like to try for these purposes CodeLab, but I do not know, on what algorithm it is necessary to process the initial image. Help me, please.

Try writing this in your native language and then posting Google's translation...

Share this post


Link to post
Share on other sites

Unfortunately, I badly know colloquial English, but I read normally. I shall try to explain once again. There is a black surface with a shone spot. In parallel it on distance "a" other black surface is located. What image of this spot will be on other black surface which is shined with this spot? I have made in Paint. Net the image of a black plane with a white spot in format BMP and would like to process in CodeLab the image so that it would become the image on the shined surface. Clearly, that the size of a spot on the shined surface will depend on distance "a" between surfaces and diameter "D" spots. But here the algorithm of calculation of parameters of a spot on the shined surface to me is not clear (brightness of each point of this spot and diameter of this spot). Probably, I should understand all over again with algorithm, and then already to ask in this conference of the help on its realizations on CodeLab. Thanks big all answered when I shall create algorithm, I shall address to you with the request for the help (if itself I can not realize it on CodeLab).

Share this post


Link to post
Share on other sites

@Boltbait:

I'm trying to draw triangles using the function

dstArgs.Graphics.FillPolygon(myBrush, myListofPoints);

in a plugin I working on... But I can't test this with CodeLab.

Is there a way to have/add this possibility for CodeLab?

Or am I missing something?

Some other functions refused:

lock (dstArgs.Graphics)
dstArgs.Surface.CopySurface(srcArgs.Surface);
dstArgs.Graphics.Clip = new Region(selection);
dstArgs.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

Thanks.

Share this post


Link to post
Share on other sites

Sorry MadJik, you can't do that kind of thing with CodeLab.

Share this post


Link to post
Share on other sites

I asked the question because it has a strange behave in plugin (FillPolygon)...

While rendering I have some lines shown and some lines hidden...

Share this post


Link to post
Share on other sites

dstArgs.Surface.CopySurface(srcArgs.Surface); 

Do NOT do this. You are required to render ONLY to the areas specified by the rectangle(s) you are given.

Share this post


Link to post
Share on other sites

I get this error at the bottom of the window, next to the OK button:

"Error at line 0: Metadata file 'C:\Program Files\Paint.NET\PdnLib.dll' could not be found (CS0006)"

Is it just me that has this error?

Thanks

Share this post


Link to post
Share on other sites
I get this error at the bottom of the window, next to the OK button:

"Error at line 0: Metadata file 'C:\Program Files\Paint.NET\PdnLib.dll' could not be found (CS0006)"

Is it just me that has this error?

Thanks

Or your PDN isn't the last version 3.05

Or you should re-download the codelab.

Pdnlib.dll is a dll from old PDN version...

Share this post


Link to post
Share on other sites

I have made the formula for calculation of the image from a shone spot on a black background and have tried to use CodeLab. In the text of the program I have marked those lines, in which I do not know how to use CodeLab. Help, please.

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

{

int x1, x2, y1, y2;

double b2, r2, bri, brisum, a = 100.0;

for(x2 = rect.Left; x2 < rect.Right; x2++)

{

for(y2 = rect.Top; y2 < rect.Bottom; y2++)

{

for(x1 = rect.Left; x1 < rect.Right; x1++)

{

brisum = 0.0; // for brightness

for(y1 = rect.Top; y1 < rect.Bottom; y1++)

{

bri = src[x1,y1].GetBrightness(); // !!! i need get Brightness source point, CodeLab - Error

b2 = (x2 - x1)^2 + (y2 - y1)^2;

r2 = b2 + a * a;

brisum = brisum + bri*Math.Sqrt(b2/r2)/r2;

} //y1

} //x1

dst[x2,y2] = brisum; // i need set brightness target point

} // y2

} // x2

}

Share this post


Link to post
Share on other sites

BoltBait, I've updated the first post to link to your CodeLab site instead of the (now outdated) zip file on the getpaint.net server.

Share this post


Link to post
Share on other sites
bri = src[x1,y1].GetBrightness(); // !!! i need get Brightness source point, CodeLab - Error

I'm not sure what you are trying to do, but you probably want to use GetIntensity(). But, you can't just assign the value of the 'brightness' back, you need to adjust the ColorBgra itself. Take a look at the source for BrightnessAndContrastAdjustment.cs

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