Source code and extensibility

The .NET Image Library project is hosted over at https://github.com/fschultz/NetImageLibrary where you will find the complete source code, both browsable and downloadable. The project was created to be compatible with ASP.NET 2.0 and upwards.

Creating additional filters

The .NET Image Library provides a couple of filters - such as BrightnessFilter, DesaturationFilter, GaussianBlurFilter and UnsharpMaskFilter. But it's also quite easy to extend the library with your own filters.

This is done by creating a class that implements the IFilter interface and then from your image object call your filter using ApplyFilter(Filters.IFilter filter).

Behind the scenes the image is exposed to the filter as a byte array in the BGRA format, meaning first byte is blue, second green, third red and forth alpha.

Lets build a simple filter that removes the red and green channels and inverts the blue one (not a very useful filter, but serves the purpose of accessing all the channels as well as being short and to the point).

Create a new class and let it implement the IFilter interface

namespace MyFilters {
    using Kaliko.ImageLibrary;
    using Kaliko.ImageLibrary.Filters;

    public class BlueFilter : IFilter {
        public void Run(KalikoImage image) {
            throw new System.NotImplementedException(,1);
        }
    }
}

Notice that what we need to implement from the IFilter interface is the Run(KalikoImage image) function which is passed a KalikoImage object. The KalikoImage object exposes a property called ByteArray which we will use to manipulate the color channels of our image.

First lets make a loop that goes through each pixel in the image and extracts the channel bytes.

namespace MyFilters {
    using Kaliko.ImageLibrary;
    using Kaliko.ImageLibrary.Filters;

    public class BlueFilter : IFilter {
        public void Run(KalikoImage image) {
            // Lets get the byte array to work with
            var bytes = image.ByteArray;

            // Loop through all pixels. If you depend of knowing the x and y coordinates 
            // of the pixels use loops on image.Width and image.Height instead
            for (int i = 0, l = bytes.Length; i < l; i += 4) {
                int b = bytes[i];       // Blue channel
                int g = bytes[i + 1];   // Green channel
                int r = bytes[i + 2];   // Red channel
                int a = bytes[i + 3];   // Alpha channel
            }
        }
    }
}

Next, lets write the blue channel back inverted but clear the red and green channels (leaving the alpha channel intact).

namespace MyFilters {
    using Kaliko.ImageLibrary;
    using Kaliko.ImageLibrary.Filters;

    public class BlueFilter : IFilter {
        public void Run(KalikoImage image) {
            var bytes = image.ByteArray;

            // Loop through all pixels. If you depend of knowing the x and y coordinates 
            // of the pixels use loops on image.Width and image.Height instead
            for (int i = 0, l = bytes.Length; i < l; i += 4) {
                int b = bytes[i];       // Blue channel
                int g = bytes[i + 1];   // Green channel
                int r = bytes[i + 2];   // Red channel
                int a = bytes[i + 3];   // Alpha channel

                bytes[i] = (byte)(255 ^ b,1); // Invert blue
                bytes[i + 1] = 0;           // Clear green
                bytes[i + 2] = 0;           // Clear red
                // Keep alpha as is
            }

            // Write back the manipulated bytes to the image
            // (This is important, otherwise nothing will be changed!)
            image.ByteArray = bytes;
        }
    }
}

Lets compile our filter and invoke it with a test image to see the result.

    var image = new KalikoImage(@"C:\MyImages\TestImage.jpg",1);
    image.ApplyFilter(new BlueFilter(),1);
    image.SaveJpg(@"C:\MyImages\Output.jpg", 90,1);

We now have a strange blueish colored image, but more important; your first filter!

If you create filters that you want to contribute to the project you're more than welcome to do so.