Buttons
Our Buttons simply fires the capture. In this case, we use the Delegate class to manipulate the scope of the call, since I don't want to use path inside my capture routine. Also this way I can't pass arguments (since I'm not using a listener that propagates an object, just a direct call), so there are three helper functions that simply forward the call to the capture routine with a number as an argument. This number indicates the position of the filter in myFilters array.
//Button handlers
colF.onPress = mx.utils.Delegate.create(this,makeColor);
shaF.onPress = mx.utils.Delegate.create(this,makeShadow);
bluF.onPress = mx.utils.Delegate.create(this,makeBlur);
//Helper functions to pass parameters
function makeShadow() { capture(0) }
function makeBlur(){ capture(1) }
function makeColor(){ capture(2) }
The main routine of our experiment is the capture function. Here we take a screenshot of the video and attach it to a MovieClip to show. This is necessary because BitmapData instances don't show by default on Stage, should be allocated inside an MC to be seen. Since we want to output any of this images, we use three different instances of BitmapData (snapshot0, snapshot1 and snapshot2) one for each filter. Then we apply the filter to the MovieClip that holds the BitmapData (filters can also be applied to BitmapData instances) Note that filter arrays of MovieClips can not be manipulated directly, you need to manipulate your own array and finally copy to the MovieClip filter array. In other words this will not work:
myMC.filters.push(myBlurFilter)
or
myMC.filters[0].blurX = 20;

So we just build a filterArray copying a slot from myFilters array and assign. At the end we attach a button to perform the JPG output
function capture(nr){
this["snapshot"+nr] = new BitmapData(output_vid._width,output_vid._height);
//draw the current state of the Video object into
//the bitmap object with no transformations applied
this["snapshot"+nr].draw(output_vid,new Matrix());
var t:MovieClip = createEmptyMovieClip("bitmap_mc"+nr,nr);
t._x = 350; t._y = 10+(nr*130); t._xscale = t._yscale = 50
//display the specified bitmap object inside the movie clip
t.attachBitmap(this["snapshot"+nr],1);
var filterArray = new Array(myFilters[nr])
t.filters = filterArray
attachMovie("print_but", "bot"+nr, 100+nr, {_x:t._x+t._width+50, _y:t._y+t._height/2})
}
The output function, called from each button is really CPU intensive, because it copy each pixel inside the image. Because data is too long (dumping the data for an image of 320 x 215 pix, I get a text file of around 500 kb), I create a new BitmapData with a matrix that resizes half the image (Matrix.resize() method) so data to pass is not too long. Note that you can apply the same filter to the snapshot, passing the result instead of the source, but results can be unexpected (I should test more this feature) In a revision of my script I decide to split this function into two: one for capturing data inside an onEnterframe (to avoid timeout risks) and other to send the data. Also I have added a second function (very similar, named outputClip, taht don't resize the source) to capture a text inside a MovieClip, that's a different kind of source.Also the code to manage progress bar is now inside the function
//preloader visible
preloader._visible = true
//Here we will copy pixels data
var pixels:Array = new Array()
//Create a new BitmapData
var snap = new BitmapData(who.width, who.height);
//Matrix to scale the new image
myMatrix = new Matrix();
myMatrix.scale(0.5, 0.5)
//Copy video image
snap.draw(who, myMatrix);
//Uncoment this line if you want to apply filters instead of just capturing source
// results should be adjusted based on your library version, not recomended
//snap.applyFilter(snap, snap.rectangle, snap.rectangle.topLeft, myFilters[nr])
var w:Number = snap.width, tmp
var h:Number = snap.height
//Build pixels array using an onEnterframe to avoid timeouts, capture a row per iteration, show a progressbar
var a:Number = 0
this.onEnterFrame = function(){
for(var b=0; b<=h; b++){
tmp = snap.getPixel32(a, b).toString(16)
trace(tmp)
pixels.push(tmp.substr(1))
}
perc = int((a*100)/w)
preloader.perc.text = perc+" %"
preloader.barra._xscale = perc
a++
if(a>w){ //Finish capturing
preloader._visible = false
sendData(pixels, h, w)
//free memory
snap.dispose()
delete this.onEnterFrame
}
}

5 most recent
Flash button as Flex icon
Tree menu
Flash Spell Checker
Flash Remoting Library
MX 2004 Chart/Poll
Articles