RSS RSS

Navigation (HowTo)





Search the wiki
»

PoweredBy
Writing an Effect
The most common type of extension is an effect or an adjustment. Although the difference between the two is quite arbitrary, the general rule is that an adjustment is designed to tweak an image (like colors or contrast), while an effect commonly provides a more dramatic change (like blurs or embossing). It is recommended that most extensions be an effect unless there is a compelling reason to make it an adjustment. For the rest of this guide, we'll use the word effect, but the same applies if you are writing an adjustment.

Like extensions in general, the design of Pinta endeavors to make writing an effect as simple as possible.

Step 1 - The Basics

This guide assumes you have created a skeleton extension as described in Getting Started Writing an Extension, and will simply add to that.

All effects inherit from Pinta.Core.BaseEffect, so let's create a new class that inherits from BaseEffect, and have our IDE implement the required methods for us.

class MyEffect : Pinta.Core.BaseEffect
{
    public override string Name
    {
        get { throw new NotImplementedException (); }
    }
}

As you can see, there is only one required method to implement, you must provide the Name of your extension. Let's add that.

public override string Name
{
    get { return "My First Effect"; }
}

Step 2 - Doing Something Interesting

Even though we've written all the required code for an effect, we haven't written any interesting code yet, so our effect doesn't do anything interesting. For this simple sample, we are going to write an effect that removes the color blue from the image. The interesting work takes place in one of the Render methods.

Render (ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
Render (ImageSurface src, ImageSurface dst, Gdk.Rectangle roi)
Render (ColorBgra* src, ColorBgra* dst, int length)
Render (ColorBgra color)

These allow you to work at different levels depending on your needs. In order, you can work on all rectangles of interest ("roi"), individual rectangles of interest, a single line, or a single pixel. Note that you only want to override one of these, and you do not want to call the base method, or else it will chain down to the more granular levels.

For our sample, we are simply going to remove the blue component from each pixel. Therefore, we only need to work at the pixel level. Here is the code we need:

protected override ColorBgra Render (ColorBgra color)
{
    color.B = 0;

    return color;
}

With this method, we are given the color of the source pixel and we need to return the color that we want the destination pixel to be. In our case, we take the source pixel, set the blue component to zero, and return it as our new color. That's it!

Step 3 - Registering the Effect

We've now written our effect, and we have our extension skeleton code so Pinta loads our extension, but we still need to tell Pinta about our effect. To do this, go back to the IExtension class and inform Pinta about your effect in Initialize using PintaCore.Effects.RegisterEffect. It's also good practice to clean up after yourself in case your extension is uninitialized.

private MyEffect my_effect;

public void Initialize ()
{
    my_effect = new MyEffect ();
    PintaCore.Effects.RegisterEffect (my_effect);
}

public void Uninitialize ()
{
    PintaCore.Effects.UnregisterEffect (my_effect);
}

Note: If you are writing an adjustment instead of an effect, you can call PintaCore.Effects.RegisterAdjustment.

Step 4 - Testing it Out

Compile your extension, place it where Pinta can find it, and run Pinta. Your effect should show up in the Effects->General menu.

Image

Run it on your favorite image to see the results!

Image

You will note that all you had to do was specify the algorithm that your effect uses and Pinta handled the rest. It handled all the painting and even added your action to the history pad so the user can undo the effect, without any additional code written by you. If the user had an area selected, only those pixels were passed to your effect.

Image

In fact, if you have multiple CPUs or multiple cores, Pinta even broke the task up in to multiple threads and ran each one on a different core!

Conclusion

With just a few lines of code, we've been able to write a very simple effect. Of course, real effects can be much more complicated. In the following tutorials, we'll expand this effect with more features.

  Name Size
- eff-1.png 6.54 KB
- eff-2.jpg 29.62 KB
- eff-3.png 2.06 KB

Last modified on Apr 01, 2011 23:23 by jpobst