Create a negative image. 
The simple task of inverting the colours in an image can be accomplished using the ColorMatrix class.
The steps to perform are as follows:
- Open the original image from disc
- Create an image in memory the same size as the original.
- Create an inverting matrix and attach it to an ImageAttributes object.
- Get a Graphics object for the image.
- Draw the original image to the copy using the ColorMatrix to invert the colours.
The C# code for this process is shown in the following listing.
Image img=Image.FromFile(<filename>);
Bitmap copy=new Bitmap(img.Width,img.Height);
ImageAttributes ia = new ImageAttributes();
ColorMatrix cm=new ColorMatrix();
cm.Matrix00=
cm.Matrix11=
cm.Matrix22=-1;
ia.SetColorMatrix(cm);
Graphics g=Graphics.FromImage(copy);
g.DrawImage(img,new Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia);
g.Dispose();
img.Dispose();
Note how the ColorMatrix properties are set so that the elements at 0,0 1,1 and 2,2 are set to -1. Setting the matrix element at 3,3 will invert the Alpha of the image also and may make it fully transparent.
Update
The ColorMatrix class can cause a few problems when used in this manner. Figure 1 shows a bitmap which was constructed in memory and inverted by the ColorMatrix in the manner described above. You can see that the resulting bitmap is not what's expected.

Figure 1: Left; a generated bitmap. Right; its inverse using the inversion matrix.
The picture above should look like the one in figure 2 but the colours have not been inverted correctly and so the whole image looks black.

Figure 2. The correct image and negative.
This effect can also be seen in photographic images that are modified by adding graphics and text to such as the one in figure 3 and it's negative.

Figure 3. An image modified with DrawString
The problem occurs when an image contains colours that have zero values in any of the RGB triplet bytes. The matrix multiplies the colour triplet byte values by the values in it's matrix and so zero multiplied by -1 is still zero. This makes the inverse of primary colours such as red or blue look black. To correct this problem it is necessary to ensure that none of the triplet values in an image are zero. This can be accomplished using a compression matrix that compresses the gamut very slightly and shifts the whole range up a little. The following code shows such a compression matrix. The values are chosen to shift the value of each byte in the image into the range 1-255 as opposed to the original range 0-255.
ImageAttributes ia=new ImageAttributes();
ColorMatrix cm=new ColorMatrix();
cm.Matrix00=cm.Matrix11=cm.Matrix22=0.99f;
cm.Matrix33=cm.Matrix44=1;
cm.Matrix40=cm.Matrix41=cm.Matrix42=.04f;
ia.SetColorMatrix(cm);
After applying this transform the image may be inverted to create the negative and the colours look as they are expected to look. Furthemore, re-inverting the image make a positive with good colour values.
Note that this technique could cause problems if you have an image with a specific colour used as a transparency key. All the colour values in the image are very slightly modified. Usually not enough to make a visible difference but the key value of Magenta (255,0,255) would be changed to something like (255,1,255) which is not identical and wouldn't therefore act as a colour key if you were still expecting Magenta.
Figure 4 shows the original image, the negative taken from the compresses image and the positive derived from that negative. Note that the colour complement of Red is Cyan and the text is indeed the correct colour.

Figure 4. The original,compressed negative and verification positive
|