Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
Creative tools for business
Digital marketing
Digital media
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Buy
Home use for personal and home office
Education for students, educators, and staff
Business for small and medium businesses
Licensing programs for businesses, schools, and government
Special offers
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
My products and services
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out My orders My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection / Flash Developer Center /

Webcam Motion Detection: Using the BitmapData API in Flash 8

by Guy Watson

Guy Watson
  • www.flashguru.co.uk

Content

  • Capturing Webcam Video
  • Video Freeze-frame
  • Monitoring the Webcam
  • Pixel Brightness
  • Difference Blend Mode
  • Changing the Color of Pixels

Created

12 September 2005

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
effects Flash Professional graphic effects video

Requirements

Prerequisite knowledge

An understanding of hexadecimal colors and ActionScript 1.0 and 2.0.

User level

Intermediate

Required products

  • Flash Professional (Download trial)

Sample files

  • webcam_old_new.zip (16 KB)

Some time ago I came across various processing experiments that monitored the active webcam for movement and allowed the user to interact with the program or art piece by moving around when in view. Until now Macromedia Flash Player has never been able to access the pixel data of a webcam feed; however, with the release of Macromedia Flash Player 8 comes an impressive and generous new feature—similar in many respects to Imaging Lingo in Director—that gives developers the power to create and modify bitmaps at runtime with ActionScript. This feature comes in the form of a new BitmapData ActionScript API.

One of my first experiments with Flash Player 8 was to try and re-create this webcam motion detection in an optimized fashion so that I could use this input as the basis for other webcam experiments, such as moving a ball around the screen by moving my hand around in view of the webcam.

Note: To view the example below, you need to have a webcam installed.

This content requires Flash To view this content, JavaScript must be enabled, and you need the latest version of the Adobe Flash Player. To view this content, JavaScript must be enabled, and you need the latest version of the Adobe Flash Player.

I set out on my journey into the realms of pixeldom and achieved the desired result. In this article, I discuss my journey and the outcome. By the end of this article, I will have taught you a little about how to use some of the new features available in the latest release of Flash Player and you should be able to use this knowledge to write some of your own experiments with webcams.

Capturing Webcam Video

Since the release of Flash Player, you can capture the video stream from a webcam and display it inside a Flash Movie. All you need to do to accomplish this feat is place a Video symbol on the Stage and write a little ActionScript. It sounds complicated, but it is actually quite simple, follow these steps to try it for yourself:

  1. Open the Library (press Control + L).
  2. Create a new Video symbol from the Library menu in the top right-hand corner.
  3. In the Video Properties dialog box, verify that the Video (ActionScript-Controlled) option is selected and click the OK button.
  4. Go to the main Timeline and select the first frame.
  5. Drag the Video symbol from the Library onto the Stage.
  6. Select the Video symbol on the Stage then open the Property inspector (Control + F3).
  7. Enter a unique name in the Instance Name field so you can talk to the video object with ActionScript. For now, enter output_vid for the instance name.
  8. Open the Actions panel on the first frame of the main Timeline (F9) and add the following code:
/* capture the video stream from the active webcam and display it inside the video object */ output_vid.attachVideo(Camera.get());
  1. That's it! Test your movie (press Control + Enter).
  2. Flash Player asks the viewer for permission to access the webcam.
  3. If permission is granted, the Video object you put on the Stage will display the video stream from the webcam.

Video Freeze-frame

In Flash Player 8, you can use the new BitmapData class to create bitmaps at runtime with ActionScript. This class holds individual pixel data and numerous methods are available to modify the pixel data inside of a BitmapData object.

One such method can be used to take a snapshot of a movie clip's current state as a bitmap object. You can also take a snapshot of the current state of a Video object, which is good news for me, because this experiment needs to access the individual pixels of the video captured from the webcam. To take a snapshot of the current state of a Video object or movie clip at runtime using ActionScript, use the draw() method of the BitmapData class.

//(From previous page) /* capture the video stream from the active webcam and display it inside the video object */ output_vid.attachVideo(Camera.get()); import flash.display.BitmapData import flash.geom.Matrix /* create a new bitmap object that is the same size as the Video object to store the pixel data */ var snapshot:BitmapData=new BitmapData(output_vid._width,output_vid._height); /* create a function that takes a snapshot of the Video object whenever it is called */ function takeSnapshot() { //draw the current state of the Video object into //the bitmap object with no transformations applied snapshot.draw(output_vid,new Matrix()); }

You can then display a BitmapData object inside of a movie clip using the new attachBitmap() method:

//create a movie clip to hold the bitmap when we attach it this.createEmptyMovieClip("bitmap_mc",this.getNextHighestDepth()); //display the specified bitmap object inside the movie clip bitmap_mc.attachBitmap(snapshot,1);

You can then call your snapshot function, for example, when a button is pressed to display a freeze frame of the video object:

snap_btn.addEventListener("click",mx.utils.Delegate.create(this,takeSnapshot));

Note: Ensure that you do not have the video object at the upper left corner of the Stage, or the bitmap_mc instance will overlap your video.

Monitoring the Webcam

To monitor changes in the video stream captured from the webcam, you need to take regular snapshots of the video object. I use setInterval to call a snapshot function every x milliseconds. Then, to actually determine whether there has been movement, at any moment in time two bitmaps have to be in memory—the bitmap created last time a snapshot was taken ("before") and a bitmap containing the current state of the video ("now"). Using the BitmapData class you can then compare the two bitmaps:

import flash.geom.Matrix import flash.display.BitmapData setInterval(this,"snapshot",100); now=new BitmapData(output_vid.width,output_vid.height); m=new Matrix(); function snapshot() { now.draw(output_vid,m); //…… code that check's difference between 'now' and 'before' before=now.clone(); }

Pixel Brightness

In my first attempt at this experiment I actually wrote some code that looped through every pixel in the current snapshot ("now") and checked for changes in the brightness of the pixel since the last snapshot ("before"). If the change in brightness of that pixel was greater than a constant tolerance value, then you can assume that there was movement in that pixel. The tolerance value is determined by trial and error, a value around 10 worked best in my experiments:

//accuracy tolerance=10; //color of the current pixel in the current snapshot nc=now.getPixel(x,y); //red channel nr=nc>>16&0xff; //green channel ng=nc>>8&0xff; //blue channel nb=nc&0xff; //brightness nl=Math.sqrt(nr*nr + ng*ng + nb*nb) //color of the same pixel in the previous snapshot bc=before.getPixel(x,y); //red channel br=bc>>16&0xff; //green channel bg=bc>>8&0xff; //blue channel bb=bc&0xff; //brightness bl=Math.sqrt(br*br + bg*bg + bb*bb); //difference in brightness between now and before d=Math.round(Math.abs(bl-nl)); if(d>tolerance) { //there was a change in this pixel }

The results were satisfactory and it did actually work to some extent (see the old-webcam SWF file below), although speed was a big problem—the larger the dimensions of the video stream the more pixels I had to check. Even a small Video object (100 pixels wide, 100 pixels high) resulted in a large ActionScript loop that looped 10,000 times to check every pixel at a regular interval. Script timeout errors were common and the program appeared to lag.

This content requires Flash To view this content, JavaScript must be enabled, and you need the latest version of the Adobe Flash Player. To view this content, JavaScript must be enabled, and you need the latest version of the Adobe Flash Player.

So, my algorithm added size restrictions to the video feed from the webcam because I had to reduce the size of the ActionScript loop; 10,000 iterations is slow and unacceptable, so back to the drawing board I go. I decided that maybe I can speed up the loop if I only check the brightness of every ten pixels in the bitmap, and it worked. However, the effect lost accuracy and didn't detect all movement in the webcam. It was time for another solution that didn't involve checking the brightness of pixels.

Difference Blend Mode

This solution came about when a friend suggested that I should take a look at the difference blend mode, one of 11 blend modes available in Flash Player 8. There are nine blend modes in Flash Player 8 and two special blend modes that require extra steps for them to function correctly. A blend mode can be used to create a composite bitmap formed by blending together the color data from two or more bitmaps with different calculations. Each different calculation is a different blend mode. I was interested in the difference blend mode, because it creates a negative effect based upon the difference in brightness of the pixels.

You can apply a blend mode to a BitmapData object with ActionScript by specifying the name of the blend mode as a string for the fourth parameter of the draw() method:

//draw the previous snapshot onto the current snapshot //using the difference blend mode now.draw(before, new Matrix(), null, "difference");

The resulting bitmap contained a negative effect; any pixels that were the same color in both the previous snapshot ("before") and the current snapshot ("now") were black. Finally, a good result; I was almost there, but I still had an ugly negative image. The next point of call was to change all the pixels that were not black to a different color. In this case, I chose green, which resulted in a bitmap that showed only the movement detected in the webcam as a green outline.

Changing the Color of Pixels

You can change the color of any specific pixel in a BitmapData object using the setPixel() method. I could have used this method to check every pixel to see whether it is black (0xFF000000), and if it isn't, then I can change the color of the pixel to green (0xFF00FF00), as follows:

w=now.width; h=now.height; for(x=0;x<w;++x) { for(y=0;y<h;++h) { if(now.getPixel(x,y) != 0xFF000000) { now.setPixel(x,y,0xFF00FF00); } } }

However, the larger the image, the more times this code will have to run. This could potentially slow down the Flash Player due to excessive loop iterations. Luckily there is another method of the BitmapData class called threshold() that you can use to isolate and replace ranges of colors in a bitmap. Because it is a native method, it is written in C code and thus it is lightning fast compared to the above code:

now.threshold(now,now.rectangle,now.rectangle.topLeft,">",0xFF111111,0xFF00FF00,0x00FFFFFF,false);

The above snippet of code basically instructs Flash Player to copy the pixels from the bitmap called now into the bitmap called now (itself), changing any pixels that have a color value that is greater than almost black (0xFF111111) to green (0xFF00FF00).

Where to Go from Here

Download the full source code and look at how everything works together in context to achieve the desired effect. I've commented the code to help you understand it. Visit Set Pixel and Flight404 for some inspirational webcam experiments—they should inspire you to develop some ideas of your own. Try and take this experiment to the next level, by using the motion detection to actually move things around the screen or to create interactive special effects. If you create something cool, send me an e-mail—I'd love to see it!

More Like This

  • Flash 411: Getting your video questions answered
  • Presenting video with the Flash video component in Dreamweaver CS3
  • Controlling web video with ActionScript 3 FLVPlayback programming
  • Creating a Talking-Head Flash Video
  • vidgal_structure_mx2004
  • Generating sounds dynamically in Flash Player 10
  • RealEyes OSMF Player Sample – Part 2: Building and configuration
  • Captioning Flash video with Captionate and the captioning-supported FLVPlayback component skins
  • Troubleshooting Flash video encoding and deployment
  • Delivering a reliable Flash video experience

Flash User Forum

More
04/23/2012 Auto-Save and Auto-Recovery
04/23/2012 Open hyperlinks in new window/tab/pop-up ?
04/21/2012 PNG transparencies glitched
04/01/2010 Workaround for JSFL shape selection bug?

Flash Cookbooks

More
02/13/2012 Randomize an array
02/11/2012 How to create a Facebook fan page with Flash
02/08/2012 Digital Clock
01/18/2012 Recording webcam video & audio in a flv file on local drive

Products

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • Mobile Apps
  • Photoshop
  • Touch Apps
  • Student and Teacher Editions

Solutions

  • Digital marketing
  • Digital media
  • Web Experience Management

Industries

  • Education
  • Financial services
  • Government

Help

  • Product help centers
  • Orders and returns
  • Downloading and installing
  • My Adobe

Learning

  • Adobe Developer Connection
  • Adobe TV
  • Training and certification
  • Forums
  • Design Center

Ways to buy

  • For personal and home office
  • For students, educators, and staff
  • For small and medium businesses
  • For businesses, schools, and government
  • Special offers

Downloads

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy Policy and Cookies (Updated)

Ad Choices

Reviewed by TRUSTe: site privacy statement