Effects Design Overview

How Paint.NET renders your effect

When Paint.NET starts, it loads all Effect DLL files it finds in its Effects folder and places entries in either the Effects menu or the Adjustments menu. When a user selects an effect from the menu, Paint.NET presents the user the effect's user interface (UI) and runs the effect's render function with the default UI values. When the user changes a slider or other UI element, Paint.NET calls the render function again with the updated values.

ROI - Rectangle of Interest

When Paint.NET is getting ready to render your effect, it breaks up the current selection into conveinent work units (rectangles, really) and calls your render function once for each rectangle of interest. Unless your selection is only a single pixel, you can be sure that your render function will never be called with the entire selection all at once. Paint.NET breaks up the selection for efficiency. That way, if you have more than one CPU (or CPU core) the work will be distributed between the cores so that the entire effect will complete faster!

This illustration shows how Paint.NET might break up this circular selection into rectangles in order to pass them to your Render function. Each colored band represents one ROI.

Render Function

If all of this sounds very complicated, don't worry. You only need to write the actual render function. CodeLab and Paint.NET will worry about all the other code including making sure that your function is multi-threaded. CodeLab even includes a default render function to get you started!

Let's take a look at the default render function.

#region UICode
int Amount1=0;	//[0,100]Slider 1 Description
int Amount2=0;	//[0,100]Slider 2 Description
int Amount3=0;	//[0,100]Slider 3 Description

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 CenterX = ((selection.Right - selection.Left) / 2)+selection.Left;
    int CenterY = ((selection.Bottom - selection.Top) / 2)+selection.Top;
    ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
    ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
    int BrushWidth = (int)EnvironmentParameters.BrushWidth;

    ColorBgra CurrentPixel;
    for (int y = rect.Top; y < rect.Bottom; y++)
        for (int x = rect.Left; x < rect.Right; x++)
            CurrentPixel = src[x,y];
            // TODO: Add pixel processing code here
			// Access RGBA values this way, for example:
            // CurrentPixel.R = (byte)PrimaryColor.R;
            // CurrentPixel.G = (byte)PrimaryColor.G;
            // CurrentPixel.B = (byte)PrimaryColor.B;
            // CurrentPixel.A = (byte)PrimaryColor.A;
            dst[x,y] = CurrentPixel;

If you notice, the main part of the render function loops through all of the pixels in the ROI from left to right and from top to bottom. It is your responsibility to write to the destination canvas every pixel in that x,y loop. Notice that this is done in the line dst[x,y] = CurrentPixel; at the end of the loop. The default render function simply copies all pixels from the source canvas to the destination canvas. The source canvas contains the unmodified image. Your job is to modify it (or replace it) on the way to the destination canvas.

Also, notice that each pixel has four parts including the Red (R), Green (G), and Blue (B) values of the pixel's color along with the Alpha (A) value (or transparency level) of the pixel. Each of these values can be modified or passed through depending on the effect you desire.

The default render loop also includes some helpful variables at the top. If your effect needs to know the center point of the selection, the primary or secondary color, or the current brush width, you can simply use the variables provided.

Now that you have a basic understanding about how Paint.NET works with effects, you are ready to learn how to create your own effects. Here is a list of tutorials on this site:

How to Write an Effect Plugin (Part 1 of 4 - Simple)
How to Write an Effect Plugin (Part 2 of 4 - Intermediate)
How to Write an Effect Plugin (Part 3 of 4 - Complex)
How to Write an Effect Plugin (Part 4 of 4 - Odds and Ends)
How to Write an Effect Plugin (Part 5 of 4 - Beyond CodeLab)
How to Write an Effect Plugin (Part 6 - Adding Help)
How to Write an Effect Plugin (Part 7 - Additional Surface)

More Information

Here is some more information that you may find useful:
Sample Code for User Interface Elements
Using the Code Editor
Designing a User Interface for Your Effect
Building a DLL File
CodeLab Help File
Check for CodeLab Updates
Learn C#



CodeLab 2.20 Released
(June 4, 2017)
This latest release of CodeLab for Paint.NET includes the Notepad++ editor and a full WYSIWYG help editor.

HTML Editor 1.5 Released
(March 31, 2016)
This latest release is a complete rewrite adding a wysiwyg editor mode and a much improved UI.

Double-Six Dominoes 3.0
(September 25, 2015)
This long-awaited refresh of the most popular dominoes game on is now available!