Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / Visual Basic
Article

A VB.NET class useful for color manipulation

Rate me:
Please Sign up or sign in to vote.
3.45/5 (4 votes)
7 Jul 2003LGPL33 min read 160.5K   692   26   21
A VB.NET class for advanced colorimetric image processing and manipulation

Introduction

Although windows seems to have some color management build into, none of this is found in any of the .NET classes, at least to my knowledge. Similarly, GDI and GDI+ contain almost no provisions for color manipulation or colorimetric image processing (there's is a color matrix, but no convolution or any more advanced image processing. It is also hard to operate on linear-light RGB values instead of gamma-corrected R*G*B* values). It seems Microsoft has no concern for the underlying principles and foundations of image processing and colorimetry, instead going for a simple pragmatic 'look I can adjust brightness or hue' type of approach ... Nothing wrong with that, but we expected more from a such a comprehensive framework as .NET (maybe we DO have to have a look at java and Java Advanced Imaging, or JAI, which seems built on a much more researched foundation). The net result (hehe) is that for my colorimetric imaging research I needed to write a support library, at first in VB6. This library has now been converted to VB.NET.

Background

An introduction to color is useful, check out Charles Poynton page to name but one.

Using the code

The library of mostly shared functions and subroutines and is not written for speed, instead I hope it is clear and easy to read. It makes heavy use of overloading and needs another class called Algebra to run, which is included in the download. Its main use is moving from one color space to another and applying gamma-correction using arrays of color triplets, but it also contains some routines for supporting image processing using unmanaged pointers, and GDI+. The supported color spaces are (a * in the notation means a non-linear light color space, e.g. after gamma-correction):

  • Generic RGB and R*G*B*. User must, obviously, provide a transform to go to other color spaces here as there are literally 100's of RGB color spaces!
  • ITU Rec 709 sRGB and sR*G*B*. A standard RGB color space used on the web, monitors and in printers.
  • CIE XYZ. A human vision based tristimulus color space encompassing all visible colors.
  • CIE L*a*b*. A perceputally uniform color space. In this space the Euclidean metric is proportional to color differences as perceived by a human observer, albeit under a rather restricted set of viewing conditions.

The library also defines several whitepoints

  • CIE D65: Noon daylight simulation with color temperature of 6500 K
  • CIE D55: Daylight simulation with color temperature of 5500 K
  • CIE A: Tungsten illumination with color temperature of 3800 K
  • CIE C: Fluorescent illumination with correlated color temperature about 5200 K
  • CIE D93: Color temperature of 9300 K, similar to some computer monitor
  • HDTVD65: High-definition television whitepoint at 6500 K

Several types of polynomial transforms between color spaces are supported, from a 3x3 linear transform to a highly non-linear, 20-term transform. The class also provides a way to compute this transform, given a set of colors in an input color space, and their desired mappings in an output color space (based on the singular value decomposition solution provided by the algebra class. Note that this routine was converted from 'Numerical Recipes in C', a well known set of numerical routines). The class also allows the use of a lookup-table or LUT to be applied prior to the polynomial transformation.

The simplest is to check out the code in the download

Sample code using the class

Here is a piece of C# code that runs through an image and transforms every pixel using a given polynomial transform and lookup table. This code also demonstrates the use of unmanaged pointers in C#, which greatly improves the speed over using managed GDI+ classes with GetPixel and SetPixel. This is not possible in VB.NET! It is assumed that the Color.vb class has been properly imported.

C#
public static unsafe void PolynomialTransform(Bitmap objBitmap, 
    float[,]Transform, float[,] LUT )
{
//Do LUT and polynomial transform on whole image ... 
//Use unmanaged pointers to go FAST. In Memory RGB values 
//are stored in the order B-G-R!!!!!! 

int x, y, iPtrPixel0; 

Rectangle rect = new Rectangle(0,0,objBitmap.Width,objBitmap.Height);
System.Drawing.Imaging.BitmapData bitmapData = objBitmap.LockBits(rect, 
System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);

iPtrPixel0 = bitmapData.Scan0.ToInt32();

//Byte pointer and corresponding managed array type 
byte * byPixel;
byte[] bySafePixel = new byte[3];

for (y = 0; y < bitmapData.Height; y ++)
  {
  byPixel = (byte *)(iPtrPixel0 + y * bitmapData.Stride);
  for (x = 0; x < bitmapData.Width; x ++)
    {
    bySafePixel[2] = *byPixel;
    bySafePixel[1] = *(byPixel + 1);
    bySafePixel[0] = *(byPixel + 2);

    Color.GammaRGBToGammasRGB(bySafePixel, Transform, LUT);
    *byPixel = bySafePixel[2];
    byPixel ++;
    *byPixel = bySafePixel[1];
    byPixel ++;
    *byPixel = bySafePixel[0];
    byPixel ++;
    }
  }
objBitmap.UnlockBits(bitmapData);
}

Points of Interest

No special points of intrest,except that even using unmanaged pointers, image processing in .NET is still pretty sloooow!

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Software Developer (Senior)
Belgium Belgium
Physicist, Biomedical Engineer, Phd in engineering. Specific expertise is in medical photography and it's related image processing, and in colourimetry.

Comments and Discussions

 
QuestionC Code Pin
stixoffire8-Apr-08 13:19
stixoffire8-Apr-08 13:19 
GeneralRe: C Code Pin
yvdh8-Apr-08 20:55
yvdh8-Apr-08 20:55 
QuestionHow to use. Pin
Alexandros5413-Sep-07 7:19
Alexandros5413-Sep-07 7:19 
AnswerRe: How to use. Pin
yvdh13-Sep-07 12:06
yvdh13-Sep-07 12:06 
GeneralRotation of Controls Pin
JK Rajesh6-Jun-07 0:07
JK Rajesh6-Jun-07 0:07 
GeneralRe: Rotation of Controls Pin
Vincent DUVERNET (Nolmë Informatique)24-Jun-07 8:06
Vincent DUVERNET (Nolmë Informatique)24-Jun-07 8:06 
GeneralConvert RGB to CMYK Colors Pin
Metexim8-Apr-06 0:44
Metexim8-Apr-06 0:44 
GeneralRe: Convert RGB to CMYK Colors Pin
Vincent DUVERNET (Nolmë Informatique)3-Oct-06 8:34
Vincent DUVERNET (Nolmë Informatique)3-Oct-06 8:34 
GeneralRe: Convert RGB to CMYK Colors Pin
Vincent DUVERNET (Nolmë Informatique)3-Oct-06 11:10
Vincent DUVERNET (Nolmë Informatique)3-Oct-06 11:10 
QuestionRe: Convert RGB to CMYK Colors Pin
JK Rajesh5-Jun-07 20:34
JK Rajesh5-Jun-07 20:34 
Generaljust what I am looking for! Pin
ivan 4525-Oct-05 6:12
ivan 4525-Oct-05 6:12 
GeneralRe: just what I am looking for! Pin
yvdh25-Oct-05 7:17
yvdh25-Oct-05 7:17 
GeneralRe: just what I am looking for! Pin
ivan 4525-Oct-05 23:36
ivan 4525-Oct-05 23:36 
GeneralRe: just what I am looking for! Pin
ivan 4525-Oct-05 23:52
ivan 4525-Oct-05 23:52 
Sorry i have just noticed the code I pasted in has used the wrong variable names - (fTransform is the same as fM). The question remains the same however!
thanks

GeneralRe: just what I am looking for! Pin
yvdh25-Oct-05 23:59
yvdh25-Oct-05 23:59 
GeneralRe: just what I am looking for! Pin
ivan 452-Nov-05 0:09
ivan 452-Nov-05 0:09 
GeneralRe: just what I am looking for! Pin
yvdh8-Dec-08 2:24
yvdh8-Dec-08 2:24 
GeneralConstruct YCbCr images Pin
yyyychan4-Mar-04 21:08
yyyychan4-Mar-04 21:08 
GeneralRe: Construct YCbCr images Pin
yvdh4-Mar-04 22:37
yvdh4-Mar-04 22:37 
GeneralRe: Construct YCbCr images Pin
yyyychan7-Mar-04 21:15
yyyychan7-Mar-04 21:15 
Questionsource code link broken ? Pin
BillWoodruff14-Jul-03 22:27
professionalBillWoodruff14-Jul-03 22:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.