Skip to content Skip to navigation

OpenStax-CNX

You are here: Home » Content » Using Chroma Key Compositing to Create Transparent Backgrounds

Navigation

Recently Viewed

This feature requires Javascript to be enabled.
 

Using Chroma Key Compositing to Create Transparent Backgrounds

Module by: R.G. (Dick) Baldwin. E-mail the author

Summary: Learn how to convert an image with a constant color background into an image with a transparent background. This involves the use of a technique commonly known as chroma key compositing.

Note:

Click ChromaKey01 to run this ActionScript program. (Click the "Back" button in your browser to return to this page.)

Preface

General

Note:

All references to ActionScript in this lesson are references to version 3 or later.

This tutorial lesson is part of a series of lessons dedicated to object-oriented programming (OOP) with ActionScript.

Several ways to create and launch ActionScript programs

There are several ways to create and launch programs written in the ActionScript programming language. Many of the lessons in this series will use Adobe Flex as the launch pad for the sample ActionScript programs.

Getting started

An earlier lesson titled The Default Application Container provided information on how to get started programming with Adobe's Flex Builder 3.

The lesson titled Using Flex 3 in a Flex 4 World was added later to accommodate the release of Flash Builder 4. (See Baldwin's Flex programming website .)

You should study those lessons before embarking on the lessons in this series.

Some understanding of Flex MXML will be required

I also recommend that you study all of the lessons on Baldwin's Flex programming website in parallel with your study of these ActionScript lessons. Eventually you will probably need to understand both ActionScript and Flex and the relationships that exist between them in order to become a successful ActionScript programmer.

Will emphasize ActionScript code

It is often possible to use either ActionScript code or Flex MXML code to achieve the same result. Insofar as this series of lessons is concerned, the emphasis will be on ActionScript code even in those cases where Flex MXML code may be a suitable alternative.

Viewing tip

I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the figures and listings while you are reading about them.

Figures

  • Figure 1 . Screen output for the program named ChromaKey01.

Listings

Supplemental material

I recommend that you also study the other lessons in my extensive collection of online programming tutorials. You will find a consolidated index at www.DickBaldwin.com .

General background information

In an earlier lesson titled Bitmap Basics , I explained the differences between Flex projects and ActionScript projects. I also introduced you to the classes named Bitmap and BitmapData .

The fundamentals of pixel processing

In the lesson titled Fundamentals of Image Pixel Processing , I showed you how to:

  • Load the contents of an image file into a BitmapData object encapsulated in a Bitmap object.
  • Use the setPixel32 , getPixels , and setPixels methods to access and modify the color content of the individual pixels that make up an image.

The organization of image information

In that lesson, I also explained how the color and transparency information for an image is stored in files and in the computer's memory. That included topics such as:

  • Vector graphics versus bitmap graphics
  • Width, height, and color depth
  • The RGB and ARGB color models
  • The effect of the transparency or alpha value (total and partial opacity or transparency)
  • Bitmap image file formats (GIF, JPEG, PNG)

Creating a transparent background

In this lesson, I will show you how to convert an image with a constant color background (such as the top image in Figure 1) into an image with a transparent background (such as the bottom image in Figure 1) .

Chroma key compositing

This involves the use of a technique commonly known as chroma key compositing .

Here is a little of what Wikipedia has to say on the subject:

"Chroma key compositing (or chroma keying) is a technique for compositing two images or frames together in which a color (or a small color range) from one image is removed (or made transparent), revealing another image behind it.

This technique is also referred to as color keying, colour-separation overlay (CSO; primarily by the BBC[1]), greenscreen, and bluescreen.

It is commonly used for weather forecast broadcasts, wherein the presenter appears to be standing in front of a large map, but in the studio it is actually a large blue or green background. The meteorologist stands in front of a bluescreen, and then different weather maps are added on those parts in the image where the color is blue."

Commonly used in computer graphics

The process is also commonly used in computer graphics where it is desired to overlay one image onto another without letting the background color of the front image show.

That is the intent of this lesson, and the process developed here will be used in a future lesson on animation.

Preview

In this lesson, I will show you to start with an image having a solid background color, such as the top image in Figure 1 and how to convert that image into one with a transparent background, such as the bottom image in Figure 1.

Figure 1: Screen output for the program named ChromaKey01.
Screen output for the program named ChromaKey01.
Missing Image

A yellow Canvas object

Both images in Figure 1 are displayed on the same yellow Canvas object.

The color of the canvas is hidden by the magenta background color of the top image. However, that magenta background is totally transparent in the bottom image, allowing the yellow color of the canvas to show through.

Discussion and sample code

The MXML file

The MXML file, shown in Listing 8, is no different from MXML files used to launch ActionScript programs in earlier lessons. Therefore, no explanation of the MXML code is warranted.

Will explain in fragments

I will explain the ActionScript code for the program named ChromaKey01 in fragments. A complete listing of the code for the ActionScript class named Driver is provided in Listing 7.

The processChromaKey method

This program illustrates the use of a custom method named processChromaKey . This method scans all of the pixels in an incoming bitmap and identifies those pixels with a color of pure magenta. The alpha values for the magenta pixels are set to zero to make them transparent. Then the bitmap is modified accordingly.

The method can easily be modified to accommodate an image background of any solid color such as green or blue. Note however, that magenta is commonly used in computer graphics, and is often referred to as "magic pink."

Beginning of the ActionScript class named Driver

The Flex code in Listing 8 instantiates a new object of the class named Driver and adds that object to the display list as a child of the Application container.

The ActionScript code for the class named Driver begins in Listing 1.

Listing 1: Beginning of the class named Driver.


package CustomClasses{
  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.geom.Rectangle;
  import flash.utils.ByteArray;
  import mx.containers.Canvas;
  import mx.controls.Image;
  import mx.events.FlexEvent;
  //====================================================//
  
  public class Driver extends Canvas {
    private var origImage:Image = new Image();

Extend the Flex Canvas class

Note that the Driver class extends the Flex Canvas class, thus making it possible to add other objects as children of an object of the Driver class.

Another reason for extending the Canvas class

I could have accomplished that purpose by extending any number of Flex container classes. However, an important characteristic of the Canvas class for this application is the ability to specify the physical locations of the child objects in absolute coordinates. Few if any other Flex containers allow you to do that,

The constructor

The constructor for the Driver class is shown in its entirety in Listing 2.

Listing 2: The constructor for the class named Driver.

    public function Driver(){//constructor
      //Make this Canvas visible with a yellow background.
      setStyle("backgroundColor",0xFFFF00);
      setStyle("backgroundAlpha",1.0);

      //Load the file mage and embed it in the swf file.
      //Note the slash that is required by FlashDevelop.
      [Embed("/dancer.png")]
      var img:Class;
      origImage.load(img);

      //Register a CREATION_COMPLETE listener
      this.addEventListener(FlexEvent.CREATION_COMPLETE,
                                         completeHandler);
    } //end constructor

Make the canvas visible

The constructor begins by setting two style properties on the Canvas object to make it yellow and opaque.

You learned how to set styles on objects in ActionScript code as early as the lesson titled What is OOP and Why Should I Care?

Load the image from the file

Then the constructor loads the image from the image file named dancer.png and embeds it in the swf file. You learned how to do this as early as the lesson titled Inheritance - The Big Picture.

No lossy compression allowed

Note that this program uses an image from a png file for demonstration purposes.

Unlike a jpg file, (which uses lossy compression) the colors that you extract from a png file are exactly the colors that were stored in the png file. That is a requirement for a chroma key process that is based on an exact color match.

An unusual requirement

There is an unusual requirement shown in Listing 2 that you haven't seen in the earlier lessons in this series.

This is the first lesson that I have written explaining a program that loaded and embedded an image file where the program was developed using FlashDevelop (see Publication Issues below).

File organization

In this case, the image file was placed in the same folder as the MXML file. Note that it was necessary for me to precede the name of the image file in Listing 2 with a slash character. I have not previously encountered that requirement when using Flex Builder 3. (Note however that inclusion of the slash character in a Flex Builder 3 project doesn't seem to cause a problem.)

Register a CREATION_COMPLETE listener

Finally, Listing 2 registers an event handler to handle CREATION_COMPLETE events fired by the Canvas object.

You learned how and why to use a CREATION_COMPLETE listener in the earlier lesson titled Encapsulation - The Big Picture.

The CREATION_COMPLETE event handler

The CREATION_COMPLETE event handler is shown in its entirety in Listing 3. This method is executed when the Canvas object has been fully created.

Listing 3: The CREATION_COMPLETE event handler.

    private function completeHandler(
                          event:mx.events.FlexEvent):void{
      //Get and save a reference to a Bitmap object
      // containing the contents of the origImage file.
      var origBitMap:Bitmap = Bitmap(origImage.content);
      
      //Set the width and height of the Canvas object 
      // based on the size of the origBitMap bitmap. Make
      // ten pixels wider and twice as high as the 
      // bitmap.
      this.width = origBitMap.width + 10;
      this.height = 2*origBitMap.height;

      //Add the original image to the Canvas object at
      // the default location of 0,0.
      this.addChild(origImage);
      
      //Clone the origBitMap to create a
      // duplicate.
      var dupBitMap:Bitmap = new Bitmap(
                           origBitMap.bitmapData.clone());
                           
      //Put the dupBitMap in a new Image object and
      // place it on the canvas below the original image.
      dupBitMap.x = 0;
      dupBitMap.y = origBitMap.height;
      
      var newImage:Image = new Image();
      newImage.addChild(dupBitMap);
      this.addChild(newImage);
      
      //Set the alpha value for all pixels in the new
      // image with a color of pure magenta to zero.
      processChromaKey(dupBitMap);

    } //end completeHandler

The call to the method named processChromaKey

With the exception of the call to the method named processChromaKey at the end of Listing 3, I explained everything in Listing 3 in the earlier lesson titled Fundamentals of Image Pixel Processing. I won't waste your time by repeating that explanation here.

Beginning of the processChromaKey method

The processChromaKey method begins in Listing 4.

Listing 4: Beginning of the processChromaKey method.

    private function processChromaKey(bitmap:Bitmap):void{
      //Get the BitmapData object.
      var bitmapData:BitmapData = bitmap.bitmapData;

      //Populate a one-dimensional byte array of pixel
      // data from the bitmapData object. Note that the
      // pixel data format is ARGB.
      var rawBytes:ByteArray = new ByteArray();
      rawBytes = bitmapData.getPixels(new Rectangle(
               0,0,bitmapData.width,bitmapData.height));
      

A reference to a Bitmap object

This method receives a reference to a Bitmap object as an incoming parameter.

It identifies all of the pixels in the incoming bitmap with a pure magenta color and sets the alpha bytes for those pixels to a value of zero.

This causes those pixels to become transparent as shown by the bottom image in Figure 1.

Nothing new in Listing 4

I explained all of the code in Listing 4 in the earlier lesson titled Fundamentals of Image Pixel Processing.

The ByteArray object is populated with pixel data

When the getPixels method returns in Listing 4, the pixels from a rectangular region that encompasses the entire bitmap are stored in the ByteArray object referred to by rawBytes .

The organization of the pixel data

The array is populated with the bitmap pixel data from the rectangular region on a row by row basis.

The first four bytes in the array belong to the pixel in the upper-left corner of the rectangular region. The next four bytes belong to the pixel immediately to the right of that one, and so on.

Four bytes per pixel

Each set of four bytes represents one pixel in ARGB format. In other words, the first byte in the four-byte group is the alpha byte. That byte is followed by the red byte, the green byte, and the blue byte in that order.

This information is critical when time comes to use the data in the array to modify the bitmap data.

Set selected alpha values to zero

The code in Listing 5 iterates through the entire set of image pixels and sets selected alpha values to zero.

Listing 5: Set selected alpha values to zero.

      //Declare working variables. Note that there is
      // no requirement to deal with the green color
      // value in this case of testing for magenta.
      var cnt:uint;
      var red:uint;
      var green:uint;
      var blue:uint;
      
      for (cnt = 0; cnt < rawBytes.length; cnt += 4) {
        //alpha is in rawBytes[cnt]
        red = rawBytes[cnt + 1];
        green = rawBytes[cnt + 2];
        blue = rawBytes[cnt + 3];
        
        if ((red == 255) && (green == 0 ) && 
                                          (blue == 255)) {
          //The color is pure magenta. Set the value
          // of the alpha byte to zero.
          rawBytes[cnt] = 0;
        }//end if
      }//end for loop      

A for loop

After declaring some working variables, Listing 5 iterates through all of the data in the ByteArray object. It extracts the red, green, and blue color bytes from each four-byte group and tests to see if red and blue are both set to full intensity with a value of 255 and green is set to zero.

If true, this is interpreted to match the magenta background color, and the value of the alpha byte in that four-bit group is set to zero.

Store the modified pixel data in the bitmap

Listing 6 copies the modified pixel data from the ByteArray object back into the bitmap, overwriting the pixel data previously stored in the bitmap.

Listing 6: Store the modified pixel data in the bitmap.

      //Put the modified pixels back into the bitmapData
      // object.
      rawBytes.position = 0;//this is critical
      bitmapData.setPixels(new Rectangle(
                0,0,bitmapData.width,bitmapData.height),
                rawBytes);
    
    } //end processChromaKey method
    //--------------------------------------------------//
        
  } //end class
} //end package

I explained all of the code in Listing 6 in the earlier lesson titled Fundamentals of Image Pixel Processing.

The end of the class

Listing 6 also signals the end of the method, the end of the class, the end of the package, and the end of the program.

Run the program

I encourage you to run this program from the web. Then copy the code from Listing 7 and Listing 8. Use that code to create a new project. Compile and run the project. Experiment with the code, making changes, and observing the results of your changes. Make certain that you can explain why your changes behave as they do.

Resources

I will publish a list containing links to ActionScript resources as a separate document. Search for ActionScript Resources in the Connexions search box.

Complete program listings

Complete listings for the program discussed in this lesson are provided in Listing 7 and Listing 8 below.

Listing 7: Listing of the class named Driver.

/*Project ChromaKey01
This project scans all of the pixels in an image to 
identify those pixels with a color of pure magenta. The
alpha value for those pixels is set to zero to make them
transparent.
*********************************************************/
package CustomClasses{
  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.geom.Rectangle;
  import flash.utils.ByteArray;
  import mx.containers.Canvas;
  import mx.controls.Image;
  import mx.events.FlexEvent;
  //====================================================//
  
  public class Driver extends Canvas {
    private var origImage:Image = new Image();
    
    public function Driver(){//constructor
      //Make this Canvas visible with a yellow background.
      setStyle("backgroundColor",0xFFFF00);
      setStyle("backgroundAlpha",1.0);

      //Load the origImage and embed it in the swf file.
      //Note the slash that is required by FlashDevelop.
      [Embed("/dancer.png")]
      var img:Class;
      origImage.load(img);

      //Register a CREATION_COMPLETE listener
      this.addEventListener(FlexEvent.CREATION_COMPLETE,
                                         completeHandler);
    } //end constructor
    //--------------------------------------------------//

    //This handler method is executed when the Canvas has
    // been fully created.
    private function completeHandler(
                          event:mx.events.FlexEvent):void{
      //Get and save a reference to a Bitmap object
      // containing the contents of the origImage file.
      var origBitMap:Bitmap = Bitmap(origImage.content);
      
      //Set the width and height of the Canvas object 
      // based on the size of the origBitMap bitmap. Make
      // ten pixels wider and twice as high as the 
      // bitmap.
      this.width = origBitMap.width + 10;
      this.height = 2*origBitMap.height;

      //Add the original image to the Canvas object at
      // the default location of 0,0.
      this.addChild(origImage);
      
      //Clone the origBitMap to create a
      // duplicate.
      var dupBitMap:Bitmap = new Bitmap(
                           origBitMap.bitmapData.clone());
                           
      //Put the dupBitMap in a new Image object and
      // place it on the canvas below the original image.
      dupBitMap.x = 0;
      dupBitMap.y = origBitMap.height;
      
      var newImage:Image = new Image();
      newImage.addChild(dupBitMap);
      this.addChild(newImage);
      
      //Set the alpha value for all pixels in the new
      // image with a color of pure magenta to zero.
      processChromaKey(dupBitMap);

    } //end completeHandler
    //--------------------------------------------------//
    
    //This method identifies all of the pixels in the
    // incoming bitmap with a pure magenta color and sets
    // the alpha bytes for those pixels to a value of
    // zero.
    private function processChromaKey(bitmap:Bitmap):void{
      //Get the BitmapData object.
      var bitmapData:BitmapData = bitmap.bitmapData;

      //Populate a one-dimensional byte array of pixel
      // data from the bitmapData object. Note that the
      // pixel data format is ARGB.
      var rawBytes:ByteArray = new ByteArray();
      rawBytes = bitmapData.getPixels(new Rectangle(
               0,0,bitmapData.width,bitmapData.height));
      
      //Declare working variables. Note that there is
      // no requirement to deal with the green color
      // value in this case of testing for magenta.
      var cnt:uint;
      var red:uint;
      var green:uint;
      var blue:uint;
      
      for (cnt = 0; cnt < rawBytes.length; cnt += 4) {
        //alpha is in rawBytes[cnt]
        red = rawBytes[cnt + 1];
        green = rawBytes[cnt + 2];
        blue = rawBytes[cnt + 3];
        
        if ((red == 255) && (green == 0 ) && 
                                          (blue == 255)) {
          //The color is pure magenta. Set the value
          // of the alpha byte to zero.
          rawBytes[cnt] = 0;
        }//end if

      }//end for loop
      
      //Put the modified pixels back into the bitmapData
      // object.
      rawBytes.position = 0;//this is critical
      bitmapData.setPixels(new Rectangle(
                0,0,bitmapData.width,bitmapData.height),
                rawBytes);
    
    } //end processChromaKey method
    //--------------------------------------------------//
        
  } //end class
} //end package

Listing 8: Listing of the MXML file.

<?xml version="1.0" encoding="utf-8"?>
<!--
Project ChromaKey01
This project scans all of the pixels in an image to 
identify those pixels with a color of pure magenta. The
alpha value for those pixels is set to zero to make them
transparent.
-->

<mx:Application 
  xmlns:mx="http://www.adobe.com/2006/mxml" 
  xmlns:cc="CustomClasses.*">
  
  <cc:Driver/>

</mx:Application>

Miscellaneous

This section contains a variety of miscellaneous materials.

Note:

Housekeeping material
  • Module name: Using Chroma Key Compositing to Create Transparent Backgrounds
  • Files:
    • ActionScript0134\ActionScript0134.htm
    • ActionScript0134\Connexions\ActionScriptXhtml0134.htm

Note:

PDF disclaimer: Although the Connexions site makes it possible for you to download a PDF file for this module at no charge, and also makes it possible for you to purchase a pre-printed version of the PDF file, you should be aware that some of the HTML elements in this module may not translate well into PDF.

Note:

Publication issues : This project was originally developed using the free open-source FlashDevelop development tool. However, because of limitations of the Connexions web site, it was necessary for me to convert the project to a Flex Builder 3 project to make it possible for you to run the program from this Connexions module.

-end-

Content actions

Download module as:

Add module to:

My Favorites (?)

'My Favorites' is a special kind of lens which you can use to bookmark modules and collections. 'My Favorites' can only be seen by you, and collections saved in 'My Favorites' can remember the last module you were on. You need an account to use 'My Favorites'.

| A lens I own (?)

Definition of a lens

Lenses

A lens is a custom view of the content in the repository. You can think of it as a fancy kind of list that will let you see content through the eyes of organizations and people you trust.

What is in a lens?

Lens makers point to materials (modules and collections), creating a guide that includes their own comments and descriptive tags about the content.

Who can create a lens?

Any individual member, a community, or a respected organization.

What are tags? tag icon

Tags are descriptors added by lens makers to help label content, attaching a vocabulary that is meaningful in the context of the lens.

| External bookmarks