Jump to content

I'm starting to update my effects


Go to solution Solved by Rick Brewster,

Recommended Posts

Now that we have paint.net 5.0.11, CodeLab v6.10 and @BoltBait's tutorials, it's time to update the outdated plugins.

 

My first attempt is to convert the classic Center Lines effect into a GPU effect. The Line Width control has been added to the new effect.

 

CenterLines_UI.png.c5f2435d3ae33d4458eb3c1f5f4c6e48.png

Below is the CodeLab script of the new plugin.

 

Spoiler
// Name:CenterLines
// Submenu:Tools
// Author:ReMake
// Title:Center Lines
// Version:2.0
// Desc:Drawing auxiliary center lines
// Keywords:paint.net|effect|center|lines
// URL:
// Help:
#region UICode
IntSliderControl lineWidth = 1; // [1,100] Line Width
ListBoxControl color = 0; // Color|Primary|Secondary|Custom
ColorWheelControl custom = ColorBgra.FromBgra(0, 0, 255, 255); // [Red?] {color} 
PanSliderControl position = new Vector2Double(0.000, 0.000); // Position
#endregion

protected override unsafe void OnDraw(IDeviceContext deviceContext)
{
    deviceContext.DrawImage(Environment.SourceImage);  // preserve background

    RectInt32 selection = Environment.Selection.RenderBounds;
    ColorBgra32 primaryColor = Environment.PrimaryColor;
    ColorBgra32 secondaryColor = Environment.SecondaryColor;
    ColorBgra32 lineColor = ColorBgra.Red;
    // converts the PanSlider values to between 0 and 1
    double posX = (position.X + 1) / 2;
    double posY = (position.Y + 1) / 2;
    // shift of lines by 1 pixel to the right/down if posX/posY = 0
    int shiftX = posX == 0 ? 1 : 0;
    int shiftY = posY == 0 ? 1 : 0;
    // converting posX/posY to actual pixel coordinates
    int centerX = (int)Math.Round(selection.Width * posX) + selection.Left + shiftX;
    int centerY = (int)Math.Round(selection.Height * posY) + selection.Top + shiftY;

    switch (color)
    {
        case 0:
            lineColor = primaryColor;
            break;
        case 1:
            lineColor = secondaryColor;
            break;
        case 2:
            lineColor = custom;
            break;
    }

    ISolidColorBrush brush = deviceContext.CreateSolidColorBrush(lineColor);

    deviceContext.DrawLine(
    centerX, selection.Top,
    centerX, selection.Bottom,
    brush, lineWidth);
    deviceContext.DrawLine(
    selection.Left, centerY,
    selection.Right, centerY,
    brush, lineWidth);
}

 

 

I am interested in what range the Line Width control should have and is there a need to use a transparency change to control Custom Color? I would also like to get suggestions and comments on code optimization.

Edited by ReMake
Edited the script after clarifications by Rick Brewster
  • Like 2
Link to comment
Share on other sites

  • Solution

Performance looks fine.

 

You don't need to create that stroke style -- you can just pass null. That's the same as creating/using the default stroke style.

  • Upvote 1

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Actually I don't think you even need to pass null -- the default value for that parameter should already be null.

 

DrawLine(x0, y0, x1, y1, brush, strokeWidth); // no need to pass strokeStyle at all

  • Thanks 1

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

20 minutes ago, AndrewDavid said:

@ReMake I plan on following you as much as I can understanding the new GPU benefits. When I paste your code into my Codelab - I receive this error

 

image.png.8c9afcd59c13a43b5d80254fd3293dc1.png

What am I not doing? :)

 

 

@ReMake created a new GPU Drawing effect.  You're trying to put that code into a new GPU Image effect.

 

Had you saved that code into a .cs file and did a File > Open in CodeLab, it would have know the type and loaded it into the proper window type for you.

 

Or, had you done a File > New > GPU Drawing Effect before pasting in your code, it would have worked properly.

 

  • Thanks 1
  • Upvote 1
Link to comment
Share on other sites

Request @ReMake

Now that I see it working - I would like to include it in my next Plugin Template release. The one I just posted is only the UI. No working script. If approved I can go on to a Chapter 2 of my plugin template.

 

Request @Rick Brewster

 Can you approve the use of your source code that resides in my Repository to create templates of 2 specific type of plugins to identify the different types of effects.  Yours is the only code I have seen that does not generate that WindowsBase error in VS2022. I think 4 templates would be a great asset for anyone coding in VS2022.

 

I think I can do Classic on my own. I did publish one, and I just remembered how I did it. :)

 

Quick while everything is in sync. I know how fast things change.

 

PaintNetSignature.png.6bca4e07f5d738b2436f83d0ce1b876f.png

Link to comment
Share on other sites

19 minutes ago, AndrewDavid said:

Request @ReMake

 

The above script is open source. You can use it as you see fit.  I created this effect following the tutorial by @BoltBait. @Rick Brewster's explanations relate to optimizing the code for the Center Lines effect. @BoltBait's  script assumes the possible use of the Line Style and is more suitable for the template.

Link to comment
Share on other sites

@ReMake the script @BoltBait provides does not allow color change, size width or position. (Baby Steps)

That is why I want to use yours. I tried on my own to figure it how to add the controls myself - now I have the answer but feel guilty using your script without your approval.

Think of the code your script contains that his does not.  That would be the next step in a tutorial - but I don't think he wants to go that far. That's the code I am referring to.

PaintNetSignature.png.6bca4e07f5d738b2436f83d0ce1b876f.png

Link to comment
Share on other sites

@BoltBait and your unfinished ones. Drawing Text in a GPU Drawing Plugin.

Followed your directions but it generates an error. I am trying to use the API references to figure it out without asking you.

 

Spoiler

There is no argument given that corresponds to the required parameter 'serviceType' of 'IServiceProvider.GetService(Type)'

 

I know the API's do not provide examples, but I should be able to find the reference needed to correct this.

AM I close? 

https://paintdotnet.github.io/apidocs/api/PaintDotNet.DirectWrite.DirectWriteFactory.CreateRef.html

PaintNetSignature.png.6bca4e07f5d738b2436f83d0ce1b876f.png

Link to comment
Share on other sites

  • 1 month later...

My second attempt is to convert the classic Color Sketch effect into a GPU effect. Applied Bokeh blur effect instead of Gaussian blur. In my opinion, this gave more expressiveness to the final image.

 

ColorSketh_ui.png.c9163bc1af71f2d3243c38809634456d.png

Below is the CodeLab script of the new plugin.

 

Spoiler
// Name:Color Sketch
// Submenu:Artistic
// Author:ReMake
// Title:Color Sketch
// Version:1.2
// Desc:Paint.net effect that simulates a sketch with colored pencils
// Keywords:paint.net|effect|color|sketch
// URL:http://www.getpaint.net/redirect/plugins.html
// Help:

#region UICode
IntSliderControl size = 3; // [1,20] Pencil tip size
IntSliderControl range = 0; // [-20,20] Range
#endregion

protected override IDeviceImage OnCreateOutput(IDeviceContext deviceContext)
{  
    BokehBlurEffect blurEffect = new (deviceContext);
    blurEffect.Properties.Input.Set(Environment.SourceImage);
    blurEffect.Properties.EdgeMode.SetValue(BokehBlurEdgeMode.Clamp);
    blurEffect.Properties.Radius.SetValue(size + 1f);

    float amount = range / 100f;
    PdnBrightnessContrastEffect bacEffect = new (deviceContext);
    bacEffect.Properties.Input.Set(blurEffect);
    bacEffect.Properties.Brightness.SetValue(amount);
    bacEffect.Properties.Contrast.SetValue(-amount);

    InvertEffect invertEffect = new (deviceContext);
    invertEffect.Properties.Input.Set(bacEffect);

    BlendEffect blendEffect = new (deviceContext);
    blendEffect.Properties.Destination.Set(Environment.SourceImage);
    blendEffect.Properties.Source.Set(invertEffect);
    blendEffect.Properties.Mode.SetValue(BlendMode.ColorDodge);

    return blendEffect;
}

 

Any criticism, suggestions and comments on code optimization.

  • Like 1
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...