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

Introducing Portable Imaging IO Library for C#

0.00/5 (No votes)
15 Sep 2015 1  
Portable video IO library for C#
All image stream readers in a single portable library.

Contents

  1. Introduction
  2. The portable imaging IO library
  3. NuGet package
  4. Conclusion

Introduction

.NET Framework lacks does not provide an video IO API. Instead we have to rely on various 3rd party libraries which offer platform-depended solutions. Current image-processing and computer-vision libraries such as AForge.NET, Accord.NET or EmguCV bring many algorithms but they lack unified API for video, camera and image directory reading and writing. The AForge.NET and Accord.NET libraries relay on DirectX which is not portable and the EmguCV merely wraps the OpenCV file and video capture but does not provide the unified API.

DotImaging.IO library is a part of DotImaging Framework providing an unified API for IO video access: web-camera support, various video-format reading / writing, image-directory reader. All operations are stream-like and are abstracted therefore do not depend on actual video source. The library is made in platform-abstract fashion. If you have been using System.IO.Stream class then you will certain be familiar with the DotImaging.IO library.

DotImaging.IO

A figure below shows the unified architecture for imaging IO reading and writing, camera capture and directory reading.

Click on the figure to enlarge the diagram.
Class diagram. The figure shows the unified API for the file, camera and directory reading and writing.

The base class that all other classes inherit is ImageStream<TImage> where TImage is the generic image type. This class contains the base stream properties, but you probably will not be using it directly. The more interesting classes, which you are going to use much more often are: ImageStreamReader<TImage> and ImageStreamWriter<TImage>. Those classes have very nice properties:

  1. the class members use the standard names for stream-like classes

    By using familiar names developer does not have to learn anything new.

  2. they are enough for all basic video IO operations

    if you just want shared IO operations which do not include specific type members the ImageStreamReader<TImage> and ImageStreamWriter<TImage> classes are enough for all video IO operations. The provided abstraction layer enables you to write programs that do not handle video stream source types separately which makes the code clean and easy maintainable.

Now, here are some concrete samples!

Reading

For the basic stream operations only ImageStreamReader class is required which is non-generic version of ImageStreamReader<TImage> class. The list below shows how to capture camera and file stream, and read image directory. The ImageStreamReader<TImage> class also implements System.IEnumerable<TImage> interface so you can use any reader inside foreach loop as shown in sample below.

  1. camera
    //capture from camera
    ImageStreamReader reader = new CameraCapture(cameraIndex: 0);
    
  2. video
    //capture from video
    ImageStreamReader reader = new FileCapture("file name.mp4"); 
    
  3. directory image stream
    //capture from folder(s)
    ImageStreamReader reader = new ImageDirectoryCapture("Image folder", "*.jpg", recursive: false); 
    
reader.Open(); //open reader

var singleImage = reader.ReadAs<Bgr<byte>>(); //read one image

//...or read all images
foreach(var image in reader)
{
   //do something with the image
}

//or read to a managed buffer 
Bgr<byte>[,] buffer = null;
reader.ReadTo(ref buffer);

reader.Close(); //close reader

More options

  • More specific options are implemented in concrete classes because they are specific for each IO source. The list below which members can be seen on the provided class diagram. They are also shown below:
  • file - FileCapture
    (inherited from VideoCaptureBase)

  • camera - CameraCapture
    (inherited from VideoCaptureBase) + camera hardware parameters - brightness, contrast, exposure, frame rate, gain, hue, saturation

  • image directory reading - ImageDirectoryCapture
    root directory info (can read recursively), file informations, current image name

Readers also implement the new async pattern so you can enjoy in asynchronously video reading.

Image<Bgr, byte> frame = null;
async void captureFrame()
{
   frame = await capture.ReadAsync(); //reads stream asynchronously
}

Writing

The library also provides the ability to compile videos from images. If you have been using System.IO.StreamWriter, you will know how to use the VideoWriter class.

Image<Bgr, byte> frame = ... //an image

ImageStreamWriter writer = new VideoWriter
                               (
                                 fileName: "output.avi", 
                                 frameSize: new Size(640, 480), 
                                 fps: 30
                               ); //create writer

writer.Open(); //open writer
writer.Write(frame); //write single image 
writer.Close(); //close writer

The VideoWriter class can also accept codec names, but the write operation may fail if the codec is not installed.

NuGet package

Although the implementation uses the unmanaged libraries the provided NuGet package is platform abstract - for now (x86 /x64 - Windows). Depending on the running OS architecture the appropriate unmanaged library is loaded so the developer does not need to handle multiple OS architectures separately. The image below shows the pre-compiled library locations.

Pre-compiled libraries. Unmanaged libraries are pre-compiled and loaded on demand depending on OS architecture.

Conclusion

This article presents the portable video IO library which offers unified stream-like interface for file and camera capture and image directory reading. The library also enables video writing. The code contains complete source as well as samples with comments. The library is the part of DotImaging Framework, a generic .NET imaging framework, so do not forget to take a peek :).

History

  • 15 October 2014 - First version released
  • 27 April 2015 - Updated
  • 15 September 2015 - Updated

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