Click here to Skip to main content
15,886,693 members
Articles / Programming Languages / C#
Article

How to implement Alpha blending

Rate me:
Please Sign up or sign in to vote.
4.80/5 (18 votes)
21 Sep 200310 min read 204K   2.7K   91   18
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:

C#
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:

C#
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:

C#
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:

C#
// 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:

C#
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:

C#
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


Written By
Web Developer
India India
Rakesh Rajan is a Software Engineer from India working at Technopark, Trivandrum in Kerala. He is a Microsoft MVP and an MCSD (.NET) with a few other certifications, and had been working in .NET for the past 3 years. He graduated majoring in Computer Science during his memorable days at Ooty (a wonderful hill station in Southern India). You can find him posting at newgroups, writing articles, working on his own projects or taking some time off by listening to music by Enya or Yanni, or reading an Archer or Sheldon.

Find his online publications here.

Rakesh blogs at http://rakeshrajan.com/blog/ and maintains a site http://rakeshrajan.com/.
He used to blog at http://www.msmvps.com/rakeshrajan/.

Drop him a mail at rakeshrajan {at} mvps {dot} org.

Comments and Discussions

 
QuestionRuns out of memory Pin
Member 1028464319-Sep-13 3:17
Member 1028464319-Sep-13 3:17 
AnswerRe: Runs out of memory Pin
Member 1028464319-Sep-13 23:49
Member 1028464319-Sep-13 23:49 
GeneralMy vote of 5 Pin
Espiritu John19-Aug-12 16:15
professionalEspiritu John19-Aug-12 16:15 
GeneralExcellent Pin
Biswas, Sumit22-Feb-09 19:51
Biswas, Sumit22-Feb-09 19:51 
Excellent Work Smile | :)

My instinct is my code

GeneralGood! Pin
jackxo198113-Nov-07 16:34
jackxo198113-Nov-07 16:34 
GeneralExactly What I needed Pin
Sukhjinder_K26-Oct-07 6:53
Sukhjinder_K26-Oct-07 6:53 
QuestionNice article, do you know anything about this bug? Pin
Paul Shaffer24-Sep-07 15:38
Paul Shaffer24-Sep-07 15:38 
QuestionAlpha Blending EMF ? Pin
khaldoun18-Jul-05 6:40
khaldoun18-Jul-05 6:40 
Generalrecognition Pin
amir mortazavi26-Jan-05 18:37
amir mortazavi26-Jan-05 18:37 
GeneralRe: recognition Pin
Rakesh Rajan30-Jan-05 19:13
Rakesh Rajan30-Jan-05 19:13 
GeneralCool, BUT.... Pin
JVMFX25-Feb-04 10:17
JVMFX25-Feb-04 10:17 
GeneralSimple Shadows Using above code Pin
ICT368616-Nov-03 11:57
ICT368616-Nov-03 11:57 
GeneralAlpha-Blend Child Forms Pin
mikasa23-Sep-03 5:32
mikasa23-Sep-03 5:32 
GeneralRe: Alpha-Blend Child Forms Pin
Rakesh Rajan23-Sep-03 17:57
Rakesh Rajan23-Sep-03 17:57 
GeneralSmall suggestion Pin
Chris Maunder22-Sep-03 15:56
cofounderChris Maunder22-Sep-03 15:56 
GeneralRe: Small suggestion Pin
Uwe Keim22-Sep-03 18:34
sitebuilderUwe Keim22-Sep-03 18:34 
GeneralRe: Small suggestion Pin
Chris Maunder22-Sep-03 18:44
cofounderChris Maunder22-Sep-03 18:44 
GeneralRe: Small suggestion Pin
Rakesh Rajan23-Sep-03 0:31
Rakesh Rajan23-Sep-03 0:31 

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.