# Blitting With AS3: Removing a Bitmap’s Background Color

##### Tutorial Details
• Difficulty: Beginner
• Platform: Flash (Flash Player 9+)
• Language: AS3
• Software used: Flash Professional CS4+, Any AS3 Compiler
• Estimated Completion Time: 20 minutes

Today, you will learn how to remove the background color from a sprite sheet using AS3, and blit the result to a bitmap canvas. Read on to learn more!

## Final Result Preview

Let’s take a look at the final result we will be working towards:

## Step 1: Drawing the Spritesheet

So, it is time to draw your spritesheet. Open up your favourite ‘pixel-art’ program and create an image of 128×128 and give it a background colour of ‘#e731f2′ which is a nice purple colour!

This is my amazing artwork:

Save your image somewhere organised and let us continue!

## Step 2: Importing the Sprite Sheet

Now, I’m call this a sprite sheet even though it is just one image. A ‘sprite sheet’ usually consists of more than one sprite but we can imagine we have more, right?

Anyway, if you are using Flash CS4 or higher, simply import your image via File | Import | Import to Library:

If you are using any other AS3 IDE, I have included the SWC file so you should probably skip this step. If you wish to embed your own images, I’m sure that your IDE of choice will have this feature.

## Step 3: Exporting the Sprite Sheet

We have now got our sprite sheet in the Library; we should really make it into a Class.

Right-click the image in the library and select ‘Properties’. Give the image the following properties:

Hit OK. If you get a warning, just ignore it; it does not matter here.

## Step 4: Creating the Document Class

If you’re not familiar with the concept of a document class, check out this Quick Tip before reading further.

Create a new ‘ActionScript 3.0 Class’ and give it the name ‘Main’. When the file has been created, save it as ‘Main.as’.

This code should be placed in our new Class:

package
{

import flash.display.MovieClip;

public class Main extends MovieClip {

public function Main()
{
// constructor code
}

}

}


We are not done yet, however! If you are using the Flash IDE, navigate to the ‘Properties Panel’ and set the ‘Document Class’ to ‘Main’. If you are wondering what that does, it means that when your application/game is run by the Flash Player, Main.as will be the class that’s linked to the SWF itself. Cool, huh?

Run the program; if you get no errors then you should be good to go!

## Step 5: Creating the Canvas

Before we do any blitting, we will first need to make a canvas to blit onto. If you are unsure of the term Blitting or would like to learn more about it, please take a look at this tutorial.

Now, we will declare a new Bitmap variable, to which we will blit (copy) the image.

private var canvas:Bitmap;


After we have done this, we will add a function called Initialize() which will allow us to set everything up neatly:

public function Main()
{
Initialize();
}


Let us create the function now:

private function Initialize():void
{
canvas = new Bitmap( new BitmapData( 550, 400, false, 0x000000 ) ); //Sets the Canvas to Black.
}


We are still not finished however, as we still have to add the imports:

import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;


Run the program; if it has a black background, it worked!

## Step 6: Initializing the SpriteSheet

Firstly, we will need to make a new variable of type SpriteSheet – which was the Class for the image we imported earlier, remember?

private var canvas:Bitmap;
private var spriteSheet:SpriteSheet;


We shall then initialize it:

private function Initialize():void
{
canvas = new Bitmap( new BitmapData( 550, 400, false, 0x000000 ) ); //Sets the Canvas to Black.
spriteSheet = new SpriteSheet(); //Sets spriteSheet to hold an instance of the image that we made.
}


Run the program and you should see nothing; let’s fix that right away!

## Step 7: Updating the Program

Now we need to add an ENTER_FRAME event. This will allow the program to update 24 times a second (24 FPS) in our case.

In the Main() function, add the following line:

public function Main()
{
Initialize();
}


Now we need to make the Update() function. Add this function after the other functions:

private function Update(e:Event):void
{

}


Don’t forget the imports:

import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;


Now we are ready to do some blitting!

## Step 8: Blitting

Here comes the interesting part!

Alright, so what we want to do is:

• Clear the canvas.
• Blit the image and remove the background colour.

In the update function, type the following code:

private function Update(e:Event):void
{

canvas.bitmapData.lock();
canvas.bitmapData.fillRect( new Rectangle( 0,0,stage.width, stage.height ), 0x000000 );
canvas.bitmapData.copyPixels( spriteSheet, new Rectangle( 0,0,128,128 ), new Point( 100, 100 ) );
canvas.bitmapData.unlock();

}


If you run this, you will get your image on the canvas! However, this is not just what we are aiming for as we wish to remove that background colour from the image.

I shall explain some of the code above first:

• canvas.bitmapData.lock(); – This line optimizes the blitting and it is a good habit to type it most of the time!
• canvas.bitmapData.fillRect(); – This line clears the canvas by filling it with a Black colour.
• canvas.bitmapData.copyPixels(); – Not very useful in our situation but copies all the pixels from part of an image.
• canvas.bitmapData.unlock(); – This works with lock() to optimize the process.

Now you should have this on the screen…

Yes, I know, you are probably right. I think we should get rid of the purple too…

## Step 9: Removing the Colour

Finally, it’s time to remove the purple colour!

What we want to do is check through every pixel; if the pixel is purple, we simply do not copy it to the canvas. To do this, we will make our own function.

Change Update() to the following:

private function Update(e:Event):void
{

canvas.bitmapData.lock();
canvas.bitmapData.fillRect( new Rectangle( 0,0,stage.width, stage.height ), 0x000000 );

CustomBlitting( spriteSheet, new Rectangle( 0,0,128,128 ), new Point( 100, 100 ), 0xE730F2 );

canvas.bitmapData.unlock();

}


Our new function (CustomBlitting(), which we have not written yet) takes most of the parameters that copyPixels does, along with an extra one: the colour we wish to remove.

Time to write the function. This code may look complicated if you have never done a nested for-loop before. The way this loop works is basically:

• For every row we have…
• Check every pixel in that row…
• Move to next row down…
private function CustomBlitting( src:BitmapData, srcRect:Rectangle, destPoint:Point, color:uint ):void
{

for( var i:int = 0; i < srcRect.height; i++ )
{
for( var j:int = 0; j < srcRect.width; j++ )
{

var currentPixel:uint = src.getPixel( srcRect.x + j, srcRect.y + i );

if( currentPixel != color )
{
canvas.bitmapData.setPixel( destPoint.x + j, destPoint.y + i, currentPixel );
}

}
}

}


Let me explain the getPixel and setPixel, although they should probably be self-explanatory:

• getPixel( x, y ); – This returns the colour of a pixel at the X,Y location.
• setPixel( x, y, color ); – This sets the colour of a pixel to color at the X,Y location of the canvas.

Now if you run the program, it works!

## Step 10: Challenges

I only have one challenge for you to do for this tutorial:

Accept an Array of colours as a parameter and remove any colours from the image that are in the array.

Good luck!

## Conclusion

I hope you have enjoyed this tutorial and have learnt something new today. If you’d like to show me your SWF with the completed challenges, leave a comment below!

• http://blog.stroep.nl/ Mark

Great tutorial. Would a BitmapData.floodFill gain extra performance for this?

• http://hardwareacceleratedreality.com Joey Clover

Hey, I think ‘floodFill()’ will give a tiny bit of performance loss compared to this method. Not sure though, I might do a performance test later. Cheers for the nice comment!

Also, about the camelcase… I know, I just have a habit of being different when it comes to naming functions, I should really do it by the standards when writing tutorials, cheers ;)

• http://www.danielsidhion.com Daniel Sidhion

Nice tip for everyone who’s learning blitting! Have you tried using the BitmapData.threshold() function as well? It would be interesting to see a comparison chart with your method, Mark’s suggested function and my suggested function.

• http://hardwareacceleratedreality.com Joseph Clover

You’re right!

I may have to try that soon. I will post my results in the comments :)

• http://www.andrewekeren.com Andrew Ekeren

Great tutorial! I’ve been interested in blitting for a long time, ever since discovering the wonderful Grant Skinner. Can’t wait to see more, thank you.

• http://hardwareacceleratedreality.com Joseph Clover

Cheers mate,
Much appreciated! :c

• Francisco

Optimize by taking the variable out of the loop and ending needless instances.

var currentPixel:uint ;

for( var i:int = 0; i < srcRect.height; i++ )
{
for( var j:int = 0; j < srcRect.width; j++ )
{

currentPixe = src.getPixel( srcRect.x + j, srcRect.y + i );

if( currentPixel != color )
{
canvas.bitmapData.setPixel( destPoint.x + j, destPoint.y + i, currentPixel );
}

}
}

• http://hardwareacceleratedreality.com Joseph Clover

Hey, thanks for that… silly mistake on my behalf. I will ask Michael to edit… Cheers!

• http://bobthecoolguy.wordpress.com/ BobTheCoolGuy

Seems like a bad idea to check every pixel every frame. Would make more sense to initially create a fixed version and cache this. While it is more flexible the way it is currently written, if the image is any size at all, it’s going to be a decent performance hit.

• http://hardwareacceleratedreality.com Joseph Clover

Hey,
I believe that they do essentially the same thing and offer the same performance… either way, flash HAS to do the same thing we did behind the scenes :)

• Ionut Cirja