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

How to implement Alpha blending

0.00/5 (No votes)
21 Sep 2003 1  
An article with code on how to create the Alpha effect (fading in and out effect). Starts with the application of alpha on images, and ends with the creation of alpha animation. This is NOT about the Per Pixel Alpha Blend used in Windows.

Sample Image - alphafx.gif

Issues covered

This article explains:

  • what the Alpha effect is
  • how to create alpha images out of image objects
  • how to draw graphic constructs (text, lines, arcs etc.) applying alpha
  • how to create a fade-in or fade-out alpha animation
  • some other intricacies to be noted

Additionally, the code gives you an example on creating alpha images.

Table of contents

Introduction

An Alpha effect is something that you definitely have seen, though may be unknowingly. It's a simple but effective visual effect where images or text fade in or out to a solid background or an image. You probably have come across it if you have used Macromedia� Flash�. It's an effect that has been used extensively in movies, television programs, games and almost any visual media that exists. It's so common that it goes unnoticed.

An alpha effect is usually employed as an animation. And animations require discrete frames to be displayed in quick succession with progressive alterations in sequence. Keeping this in mind, the first part of this article explains how to create a single alpha image out of image objects. Next, it explains how you could create this effect when calling drawing methods like that of lines, arcs, text etc. The article then goes on to explain how to create an animation out of all that. Finally, it points out some little details worth to be noted.

The code uses the following additional namespaces:

  • System.Drawing
  • System.Drawing.2D
  • System.Drawing.Imaging

Applying alpha on images

If you have been working in C# for some time, you might want to skip the subsection 'The first steps' and proceed to 'Step 1'. 'The first steps' gives you a small introduction to graphics programming.

The first steps

To work with graphics or with formatted text in .NET, you usually rely on GDI+. GDI+ is simply an API (Application Programming Interface) that helps programmers work with display devices and graphics better.

To draw some graphics, you need an area where you want to work upon. Or in better words, a surface where the graphics will be drawn. These surfaces can be portions of display devices or of images themselves (this is how you modify an image programmatically). To represent a surface and to work on it, you use a Graphics object (System.Drawing namespace).

So, the first step in applying alpha is to create a Graphics object of the surface you want to draw onto.

Step 1: Creating a Graphics object

If the surface you want to work upon is a portion of a control, you call the control's CreateGraphics method to create it's Graphics object. For example, suppose you have a PictureBox control, pictureBox1 in your form; the following code will let you create it's Graphics object:

Graphics gra = pictureBox1.CreateGraphics();

If the surface you want to work upon is a portion of an image, you call the static Graphics.FromImage method to create the image object's Graphics object. Image objects are represented by instances of either the Bitmap or the Metafile class, both of which derive from the abstract Image class. For example, the following code creates a Bitmap object from a file logo.jpg, and then creates it's Graphics object.

Bitmap logo = new Bitmap("logo.jpg");
Graphics gra = Graphics.FromImage(logo);

The Graphics class contains several methods you can use to create basic graphics like drawing rectangles, filling regions and so on. But to apply alpha on images, you need more control. For this, you will use two classes: ImageAttributes and ColorMatrix (System.Drawing.Imaging namespace). An ImageAttributes object lets you control the way graphics is rendered by letting you specify different settings like color adjustment, grayscale adjustment and more. The ColorMatrix class can be considered as a helper class whose instances are parameters in most of the methods of the ImageAttributes class. It contains values specifying the Alpha, Red, Green and Blue channels.

So, the next step is to initialize a color matrix object and pass it to the appropriate method of an ImageAttributes object.

Step 3: Creating the ImageAttributes and ColorMatrix objects

A few basics: An image is composed of colors. All the colors of an image is usually made up of three primary colors: Red, Green and Blue (RGB in short). Different combinations of these three primary colors create different colors which are known as composite colors. Normally, each primary color can take any value in the range of 0 to 255. When all the primary colors have the value 0, then it creates the color black. When all of them are 255, it's white. A Channel is an entity present in images, which can be thought of as what defines the visibility of a specific primary color. For example, if you cut off the Red channel, no Red color (of range 0-255) will be displayed. Additionally, an Alpha channel exists in some images, which defines the total visibility of the image. Hence, an image may have RGBA as it's channels. The primary colors, the range of values a primary color can take, the channels, etc. are all dependent on the image format used. That is off-track.

A color matrix is a matrix that contains values for channels. It's a 5x5 matrix which represents values for the Red, Green, Blue, Alpha channels and another element w, in that order (RGBAw).

In a ColorMatrix object, the diagonal elements of the matrix define the channel values viz. (0,0), (1,1), (2,2), (3,3), and (4,4), in the order as specified before - RGBAw. The values are of type float, and range from 0 to 1. The element w (at (4,4) ) is always 1.

What you have to do is to create a new ColorMatrix object and set the channel values as required. To do this, you access the properties representing the respective matrix elements. For example, the Matrix00 property lets you access the element at (0,0).

Once you initialize the ColorMatrix object, you create a new ImageAttributes object, and assign the newly created ColorMatrix object to it. This is done by calling the SetColorMatrix method on the ImageAttributes object. For example, the following code creates a ColorMatrix object, sets it's alpha value to 0.5, and creates a new ImageAttributes object, setting it's color matrix to the one just created:

ColorMatrix cm = new ColorMatrix();
cm.Matrix33 = 0.5;
ImageAttributes ia = new ImageAttributes();
ia.SetColorMatrix(cm);

The final step is to draw the original image with the ImageAttributes object just created. Using this ImageAttributes object would draw the original image with the alpha value we set in the color matrix, creating the alpha image.

Step 4: Drawing the alpha image

To draw the alpha image, we call one of the overloads of the Graphics.DrawImage method on the Graphics object. Note that this overload should accept an ImageAttributes object with which we would specify the render modifications. So select an appropriate overload and call it. For example, the following code draws the image ImageBitmap at the location specified, with the ImageAttributes object ia:

gra.DrawImage(ImageBitmap,
    new Rectangle(0,0,ImageBitmap.Width,ImageBitmap.Height),
    0,0,ImageBitmap.Width, ImageBitmap.Height, GraphicsUnit.Pixel,
    ia);

The following is a complete code listing for the whole set of steps we went through:

// Get a picture box's Graphics object

Graphics gra = pictureBox1.Graphics;

// Create a new color matrix and set the alpha value to 0.5

ColorMatrix cm = new ColorMatrix();
cm.Matrix00 = cm.Matrix11 = cm.Matrix22 = cm.Matrix44 = 1;
cm.Matrix33 = 0.5;

// Create a new image attribute object and set the color matrix to

// the one just created

ImageAttributes ia = new ImageAttributes();
ia.SetColorMatrix(cm);

// Draw the original image with the image attributes specified

gra.DrawImage(ImageBitmap,
    new Rectangle(0,0,ImageBitmap.Width, ImageBitmap.Height),
    0,0,ImageBitmap.Width, ImageBitmap.Height, GraphicsUnit.Pixel,
    ia);

Applying alpha on graphic constructs

The Graphics class consists of several specific draw methods like that of lines, arcs etc. When you use such methods, it is possible to apply alpha right when you use them, rather than applying it to the image in total as explained above. This would undoubtedly be more straightforward illustrated as follows:

All the specific graphic construct draw methods of the Graphics class (except DrawIcon and DrawImage) makes use of either a Pen or a Brush object as an argument. Both the Pen and Brush classes have a common underlying element - Color; which means that both these classes use a Color structure either directly or indirectly. We make use of this fact to make the application of alpha simpler.

A Color structure defines not only the RGB channels, but also the Alpha channel. To create a new Color object together defining it's alpha, we use the Color.FromArgb method:

public static Color FromArgb(
    int alpha,
    int red,
    int green,
    int blue
);

where the value range of each element is 0-255.

The idea here is, to initialize a Color object with the desired alpha value, to create the appropriate Pen or Brush objects from this Color structure, and to call the specific draw method passing the Pen or Brush object just created. This would draw the graphic with the alpha value set in the Color structure, and would create the same alpha effect as you would have obtained using the first procedure.

To create a Pen object on the basis of a Color object, use the Pen.Pen(Color) constructor.

To create a Brush object on the basis of a Color object, use the SolidBrush.SolidBrush(Color) constructor. The SolidBrush class is derived from the abstract Brush class. There are other classes derived from the Brush class some of which use the Color structure; but that's a different story.

The following code draws a string 'Text' in black with alpha 100. (Note that 100 is not 100% in this procedure. This is likely to go unnoticed.)

gra = e.Graphics;
gra.DrawString("Text", new Font("Verdana", 24), 
    new SolidBrush(Color.FromArgb(100,0,0,0)), 0,0 );

In a similar manner, alpha effect on other constructs can be carried out.

Creating an alpha animation

An animation exhibiting alpha effect is usually of two types: fade-in and fade-out. A fade-in animation starts with a black (usually) background and ends with the actual image. Technically, the starting frame is of alpha zero, and the ending frame is of alpha 100. A fade-out animation is the exact opposite. The background may also be another image.

To create an animation of either of the two types, you need to create a whole sequence of such alpha images and display them in order.

First, decide on the number of discrete alpha images you need. To create a smooth effect, a minimum of fifteen frames is recommended. Once you have decided on the number, create a Bitmap array with this size. Then start a loop, and create Bitmap objects of the required alpha value within the array. Finally, depending on the destination, either create a Graphics object and draw the image, or set the control's Image property to this object. This method of creating an image sequence in the memory and then displaying them is known as Double Buffering.

The following code creates an image sequence in the procedure as mentioned above:

int FrameCount = 15;
float opacity = 0.0F;
Bitmap original = new Bitmap("logo.jpg");
Bitmap[] frames = new Bitmap[FrameCount];
for(int x=0; x<FrameCount; x++, opacity+=0.1F)
{
  Bitmap alpha = new Bitmap(original, original.Size);
  Graphics gra = Graphics.FromImage(alpha);
  gra.Clear(Color.Transparent);
  ColorMatrix cm = new ColorMatrix();
  cm.Matrix00 = cm.Matrix11 = cm.Matrix22 = cm.Matrix44 = 1;
  cm.Matrix33 = opacity;
  ImageAttributes ia = new ImageAttributes();
  ia.SetColorMatrix(cm);
  gra.DrawImage(original, 
      new Rectangle(0,0,original.Width,original.Height),
      0,0,original.Width, original.Height, GraphicsUnit.Pixel, ia);
  frames[x] = alpha;
}

For displaying them, you might want to use a timer, or the control's unique paint handler.

Miscellaneous stuff

Compositing mode

When you obtain a Graphics object from a surface, there may be some image already drawn on that same surface. Drawing a new image with full alpha on top of it overwrites the old image. Drawing a new image with partial alpha won't do so necessarily. Two possibilities exist in this case: either the new image overwrites the old image, or the new image blends with the old image (the old image shows through partially). To define the way the new image is to be drawn, you use the CompositingMode property of the Graphics class.

CompositingMode, defined in the System.Drawing.Drawing2D namespace, is an enumeration with two members:

  • SourceCopy, which specifies that new images overwrite old images
  • SourceOver, which specifies that new images are blended with old images with respect to the alpha component of the new image.

So, once you create a Graphics object, set it's CompositingMode property to the required member and proceed.

Note that when you are creating a Graphics object from a control, the new image automatically overwrites the old image regardless of whether you set it's CompositingMode to SourceCopy or not.

Also note that it's the opposite when you create a Graphics object from an Image object - new images are blended to the old ones.

Instead of setting CompositingMode to SourceCopy, you could attain the same effect by clearing the surface with the Graphics.Clear method passing some color like Color.Transparent before drawing.

Conclusion

That's all. Go!

Updates

  • 22/09/2003: Just posted. Thinking about adding an animation portion within the code, and about whether there are other details to be added.

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