Rotating Colors

Rotation in a four-dimensional color space is difficult to visualize. We can make it easier to visualize rotation by agreeing to keep one of the color components fixed. Suppose we agree to keep the alpha component fixed at 1 (fully opaque). Then we can visualize a three-dimensional color space with red, green, and blue axes as shown in the following illustration.

9ya02xa6.recoloring03(en-us,VS.71).gif

A color can be thought of as a point in 3-D space. For example, the point (1, 0, 0) in space represents the color red, and the point (0, 1, 0) in space represents the color green.

The following illustration shows what it means to rotate the color (1, 0, 0) through an angle of 60 degrees in the Red-Green plane. Rotation in a plane parallel to the Red-Green plane can be thought of as rotation about the blue axis.

9ya02xa6.recoloring04(en-us,VS.71).gif

The following illustration shows how to initialize a color matrix to perform rotations about each of the three coordinate axes (red, green, blue).

9ya02xa6.recoloring05(en-us,VS.71).gif

The following example takes an image that is all one color (1, 0, 0.6) and applies a 60-degree rotation about the blue axis. The angle of the rotation is swept out in a plane that is parallel to the red-green plane.

Dim image = New Bitmap("RotationInput.bmp")
Dim imageAttributes As New ImageAttributes()
Dim width As Integer = image.Width
Dim height As Integer = image.Height
Dim degrees As Single = 60F
Dim r As Double = degrees * System.Math.PI / 180 ' degrees to radians
Dim colorMatrixElements As Single()() = { _
   New Single() {CSng(System.Math.Cos(r)), _
                 CSng(System.Math.Sin(r)), 0, 0, 0}, _
   New Single() {CSng(- System.Math.Sin(r)), _
                 CSng(- System.Math.Cos(r)), 0, 0, 0}, _
   New Single() {0, 0, 2, 0, 0}, _
   New Single() {0, 0, 0, 1, 0}, _
   New Single() {0, 0, 0, 0, 1}}
      
Dim colorMatrix As New ColorMatrix(colorMatrixElements)
      
imageAttributes.SetColorMatrix( _
   colorMatrix, _
   ColorMatrixFlag.Default, _
   ColorAdjustType.Bitmap)
      
e.Graphics.DrawImage(image, 10, 10, width, height)
      
' Pass in the destination rectangle (2nd argument), the upper-left corner 
' (3rd and 4th arguments), width (5th argument),  and height (6th 
' argument) of the source rectangle.
e.Graphics.DrawImage( _
   image, _
   New Rectangle(150, 10, width, height), _
   0, 0, _
   width, _
   height, _
   GraphicsUnit.Pixel, _
   imageAttributes)
[C#]
Image image = new Bitmap("RotationInput.bmp");
ImageAttributes imageAttributes = new ImageAttributes();
int width = image.Width;
int height = image.Height;
float degrees = 60f;
double r = degrees*System.Math.PI/180; // degrees to radians

float[][] colorMatrixElements = { 
   new float[] {(float)System.Math.Cos(r),  (float)System.Math.Sin(r),  0,  0, 0},
   new float[] {(float)-System.Math.Sin(r),  (float)-System.Math.Cos(r),  0,  0, 0},
   new float[] {0,  0,  2,  0, 0},
   new float[] {0,  0,  0,  1, 0},
   new float[] {0, 0, 0, 0, 1}};

ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

imageAttributes.SetColorMatrix(
   colorMatrix, 
   ColorMatrixFlag.Default,
   ColorAdjustType.Bitmap);

e.Graphics.DrawImage(image, 10, 10, width, height);

e.Graphics.DrawImage(
   image, 
   new Rectangle(150, 10, width, height),  // destination rectangle 
   0, 0,        // upper-left corner of source rectangle 
   width,       // width of source rectangle
   height,      // height of source rectangle
   GraphicsUnit.Pixel,
   imageAttributes);

The following illustration shows the original image on the left and the color-rotated image on the right.

9ya02xa6.colortrans5(en-us,VS.71).gif

The following illustration shows a visualization of the color rotation performed in the preceding code.

9ya02xa6.recoloring06(en-us,VS.71).gif