Paint.NET Effects updated

It's been a while since I've been blogging. I've been very busy with several projects, professionally with U2U Consult as well as personally. Anyway, I have decided to spend a bit more time on this again, and here's the first result.

I've updated my Paint.NET effects. Version 3.3 is a performance update mainly. All effects and adjustments have been optimized, with some spectacular results on the popular Drop Shadow effect. Depending on the scenario (i.e. image and parameter values), I have seen this effect to be more than a hundred times faster!

As a result, I have been able to increase the range for values of the offset, blur and widening parameters. Several users have requested a shadow opacity parameter, so that has been added as well.

Note that the Drop Shadow effect has moved to the Object effect menu, as requested by several users on the Paint.NET forum. And in case you haven't heard: Paint.NET is free image and photo editing software for Windows computers.

Download the effects from my download page.

Enjoy!

Technorati tags: , , , , ,

PaintDotNetEffects updated for Paint.NET 3.30

My framework for Paint.NET effects, and the 13 effects, have been updated for Paint.NET 3.30.

You'll need Paint.NET 3.30 Beta 2 for these to work.

What's new:

  • Drop Shadow effect now has a color picker, as have the duotone and monochrome adjustments
  • The behavior of the sliders in several effect dialogs has been improved
  • The framework has support for some of the new features of Paint.NET 3.30
  • The icon for the Drop Shadow is back to the white circle (not that it really matters, but anyway)

Download the latest version, with full source code, from my download page.

Effects per DLL:

  • Vandermotten.PaintDotNetEffects.dll: You allways need this dll. It includes the framework used by the other dll's.
  • Vandermotten.PaintDotNetEffects.Blurs.dll: "Average Blur" and "Smart Blur" effects, under the Blurs effect menu.
  • Vandermotten.PaintDotNetEffects.DropShadow.dll: The "Drop Shadow" effect, under the Stylize effect menu. With offset, widening, blur and a color picker.
  • Vandermotten.PaintDotNetEffects.Duotones.dll: "Duotone Light" and "Duotone Ink on Paper" adjustments. Two color pickers for each.
  • Vandermotten.PaintDotNetEffects.FadeEdge.dll: "Fade Edge" effect, under the Photo effect menu.
  • Vandermotten.PaintDotNetEffects.Monochromes.dll: "Cyanotype", "Sepia 2", "Grayscale on Colored Paper" and "Monochrome Ink on Paper" adjustments. Did I mention the color pickers yet?
  • Vandermotten.PaintDotNetEffects.Samples.dll: You probably don't want these, unless you're looking at the source code. "Darken", "Lighten" and "Negative" adjustments.

AssemblyInfo and Paint.NET Effects Updated

There's a bug fix for AssemblyInfo, my .NET Reflector language plug-in. The type name of generic types now renders correctly.

There's also a new version of the Paint.NET effects I released only two days ago. I got quite some feedback from the Paint.NET user community. I've split the framework from the demo's, and I split the demo's into 6 separate dll's. That makes it easier for Paint.NET users to choose which effects they want to install. And the effects now show up in the standard localized menu's. Last but not least, there's a small but important optimization in the Drop Shadow effect.

Both can be downloaded from my download page.


13 Paint.NET Effects and a Framework to create your own

I've created 13 "new" Paint.NET effects (9 adjustments and 4 effects) and a framework to create your own effects more easily. Download Vandermotten.PaintDotNetEffects from my download page. Full source code is included in the download.

The nine adjustments are:

  • Cyanotype: the classical blueprint look, see http://en.wikipedia.org/wiki/Cyanotype. This actually is a demonstration of the Monochrome Ink on Paper adjustment, see below.
  • Darken: darkens an image, simple demo of the framework. See also below.
  • Lighten: lightens an image, simple demo of the framework.
  • Duotone Ink on Paper: see http://en.wikipedia.org/wiki/Duotone. Set the two ink colors using the Colors window.
  • Duotone Light: a variation on the traditional duotone, where two colored light sources are mixed additively. Set the two light colors using the colors window.
  • Grayscale on Colored Paper: well, it looks like a grayscale image on colored paper :-). Set the paper color using the colors window. Or maybe it's a black and white image projected with a colored light...
  • Monochrome Ink on Paper: looks like a grayscale image printed with one color ink. Set the ink color using the colors window.
  • Negative: duplicate of the built-in Invert Colors adjustment, provided as a very simple demo of the framework. See also below.
  • Sepia: simple demo of the Grayscale on Colored Paper adjustment, configurable though.

And four effects:

  • Drop Shadow: creates a drop shadow under an image with transparency. Offset, widening and shadow blur can be controlled. The widening option also allows creating outlines around images. Shadow color is set using the colors window before starting the effect.
  • Fade Edge: a simple demo of the framework. Fades the edge of an image. Width and power can be controlled.
  • Average Blur: averages all pixels within a controlled radius.
  • Smart Blur: averages pixels in a controlled radius if their color is close enough to the center color. This is very useful to reduce aliasing from scanned prints, especially of cartoon-like images.

So how do you create an effect with the framework? Let's starts with a very simple adjustment example: negative. An adjustment processes one pixel at a time, where one color is transformed into another color, no matter where the color appeared in the original image. In essence, an adjustment is a function that takes one color parameter, and returns another one.

public delegate ColorBgra Adjustment(ColorBgra source);

To create a Paint.NET adjustment effect, create a dll project and add references to PaintDotNet.Base, PaintDotNet.Core, PaintDotNet.Effects, and ... Vandermotten.PaintDotNetEffects. Create a class inheriting from Vandermotten.PaintDotNetEffects.SmartAdjustment:

using PaintDotNet;
using PaintDotNet.Effects;
using Vandermotten.PaintDotNetEffects;

[EffectCategory(EffectCategory.Adjustment)]
public class NegativeAdjustment : SmartAdjustment
{
public NegativeAdjustment()
: base("Negative")
{
}

protected override Adjustment AdjustmentToRender
{
get
{
return c => new ColorBgra()
{
B = (byte)(255 - c.B),
G = (byte)(255 - c.G),
R = (byte)(255 - c.R),
A = c.A
};
}
}
}

Attribute the class with the EffectCategory attribute, to make it appear under the adjustments menu. In the constructor, call the base constructor to set a name, and optionally an icon, submenu and effect flags. All you need to do now is override the AdjustmentToRender property. Return a function that transforms one color into another and you're done.

Notice also how easy it becomes to unit test your adjustments. Just call the function returned by AdjustmentToRender from your unit tests and validate the results.

And what about configurable adjustments, such as Darken? Rick has made developing configurable effects much easier than it used to be, but SmartProperties go one step further:

[EffectCategory(EffectCategory.Adjustment)] 
public class DarkenAdjustment : SmartAdjustment
{
public DarkenAdjustment()
: base("Darken", null, EffectFlags.Configurable)
{
}

SmartDoubleProperty factor = new SmartDoubleProperty("Factor")
{
DefaultValue = 1.5,
MinValue = 1,
MaxValue = 16
};

protected override IEnumerable<ISmartProperty> GetProperties()
{
return new ISmartProperty[] { factor };
}

protected override Adjustment AdjustmentToRender
{
get
{
if (factor == 1)
{
return c => c;
}
return c => new ColorBgra()
{
B = (byte)(c.B / factor),
G = (byte)(c.G / factor),
R = (byte)(c.R / factor),
A = c.A
};
}
}
}

Tell the base class the effect is configurable, declare and initialize the properties (of type double, int or bool for now), and override GetProperties(). You can then use those properties in your AdjustmentToRender implementation.

Notice how AdjustmentToRender varies the function it returns by the values of the configuration properties. This is a key aspect of the functional programming style: this basic form of partial evaluation becomes almost trivially easy to implement, and can yield important performance benefits. In fact, the Drop Shadow effect in the download can be terribly slow for certain image and parameter combinations, but this partial evaluation, combined with the lazy evaluation of some parts of the function, make it perform very fast in most cases.

Non-adjustment effects work similarly to adjustments, but there are some very important differences as well. More about those in a later post. Or take a look at the source code that's included in the download. You'll need Visual Studio 2008 to compile it, but you can use the framework from Visual Studio 2005 as well (though you'll miss the convenient C# 3.0 syntax).

Enjoy.