Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Introducing Portable Generic Image Library for C#

0.00/5 (No votes)
15 Sep 2015 3  
Portable generic image library for C#

The .NET does not provide the truly portable image format. System.Drawing.Bitmap and does not provide generic interface which imposes compile-time constraints. EmguCV's generic image provides the generic interface but is heavily coupled with OpenCV and does not provide non-generic interface which has basic data manipulation methods necessary for many algorithms. All mentioned image types do not provide a unified interoperability needed when mixing image-processing algorithms from different libraries.

The DotImaging Framework approach is to provide color types which is used by a 2D array which represents an managed image. This way an already known built-in array type is leveraged which provides the base for many image-processing algorithms which can be written as extensions. The interoperability with other image types is achieved through extension assemblies such as DotImaging.BitmapInterop. The reasons why the library is appealing are the following:

  • leverages existing .NET structures
    The primary imaging structure is the built-in .NET array (e.g. Bgr<byte>[,] - a Bgr 8-bit image)

  • portable - designed for the Web
    It is not tied with any platform-specific API thus enabling simple multi-platform usage.

  • lightweight (no 3rd party dependencies), but powerful
    There are no 3rd-party dependencies and packages are small.

  • so simple, you don't need a help file
    Upon a NuGet package installation an appropriate read-me file is shown which provides short samples which demonstrate what you can do with it.

 

Components / NuGet packages

DotImaging.GenericImage
.NET image array extensions. Color and depth conversions. Slim unmanaged structure for fast pixel manipulation.

//convert to grayscale and flip
Bgr<byte>[,] image = ImageIO.LoadColor("sample.jpg").Clone();
Gray<byte>[,] grayIm = image.ToGray()
                            .Flip(FlipDirection.Horizontal);

 

DotImaging.IO
A unified API for IO image access (camera, file, image directory). Portable image loading/saving.

//create camera (file or image-directory) capture
var reader = new CameraCapture();
reader.Open();
//read single frame
var frame = reader.ReadAs<Bgr<byte>>();
reader.Close();

 

DotImaging.Linq
2D array Linq extensions

//create a managed image
Bgr<byte>[,] image = ...;
//get the modified blue channel
var modifiedImage = image.AsEnumerable()
                     .Select(x => x.B / 2)
                         .ToArray2D(image.Size());

 

DotImaging.Drawing
.NET image drawing array extensions.

//create a managed image
var image = new Bgr<byte>[480, 640];
//draw something
image.Draw(new Rectangle(50, 50, 200, 100), Bgr<byte>.Red, -1);
image.Draw(new Circle(50, 50, 25), Bgr<byte>.Blue, 5);

 

DotImaging.BitmapInterop
Interoperability extensions between .NET array and Bitmap.

var image = new Gray<byte>[240, 320];
var bmp = image.ToBitmap(); //to Bitmap
var imageFromBmp = bmp.ToArray() as Bgr<byte>[,]; //from Bitmap

 

DotImaging.Primitives2D
Portable 2D drawing primitives (Point, Size, Rectangle, ...)

Fast pixel manipulation

Sometimes the pixel access speed through the built-in 2D .NET array is not enough. The boundary checking can be eliminated by using the unsafe code. Also, by having the image representation as unmanaged pointer and size, the managed array can be easily converted to various 3rd party image structure formats. The built in Image<TColor> provides an unmanaged pixel access. An example usage is shown below:

Bgr<byte>[,] image = ...

using(Image<Bgr<byte>> uIm = image.Lock())
{
   Bgr8* ptr = (Bgr8*)uIm.ImageData;
   ptr->B = 8; //set the image[0, 0].B = 8;
}

A reverse transformation acquires data-copy which can be done as:

Image<Bgr<byte>> uIm = ...
Bgr<byte>[,] image = uIm.Clone();

An unmanaged image also supports OpenCV's IplImage interoperability, which can be useful is using some OpenCV's functions directly or via EmguCV library.

Image<Bgr<byte>> uIm = ...
IplImage iplImage = uIm.AsOpenCvImage();

The unmanaged class also implements the non-generic interface IImage which enables passing generic image instance where generic type is not possible or not desirable. The interface itself contains numerous extensions so even the unmanaged non-generic representation is quite useful. Please bare in mind that unmanaged class is here primary for interoperability and fast pixel access. .NET built-in array is the primary imaging object.

 

Conclusion

This article presents the portable generic image library which offers interoperability with image formats from other libraries: EmguCV, OpenCV and the standard .NET types (Bitmap, BitmapData, 2D and 3D array). The framework is the foundation for the Accord.NET Extensions Framework - framework for image processing and computer vision. The DotImaging sets focus on .NET native array as primary imaging object, offers extensibility support via extensions, and provides unified platform-abstract imaging IO API, so do not forget to take a peek :).

History

  • 13 October 2014 - First version released
  • 28 April 2015 - Updated
  • 15 September 2015 - Major revision

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here