views:

537

answers:

3

i've created a bitmap with data and placed it into a sprite so to receive mouse events. however, i'm struggling with reading the BitmapData within the sprite.

function showBitmapData(e:Event):void
    {
    var bData:BitmapData = new BitmapData(video.width, video.height);
    bData.draw(video);

    var bmap:Bitmap = new Bitmap(bData);
    bmap.x = 220;
    bmap.y = 20;
    bmap.scaleX = bmap.scaleY = 2;

    canvas = new Sprite;
    addChild(canvas);
    canvas.addChild(bmap);

    //Mouse Track Pixel Colors
    canvas.addEventListener(MouseEvent.CLICK, readPixel);
    }

function readPixel(e:MouseEvent):void
    {
    var hex:uint = e.bmap.bData.getPixel32(mouseX, mouseY); // <- is the problem?
    var pixelAlpha:int = (hex >>> 0x18) & 0xff;
    var red:int = (hex >>> 0x10) & 0xff;
    var green:int = (hex >>> 0x08) & 0xff;
    var blue:int = hex & 0xff;

    colorText.text = "Red:" + red + " Green:" + green + " Blue:" + blue + " Alpha:" + pixelAlpha;
    }
+1  A: 

You are trying to read the field bmap from e who is a MouseEvent and don't have such field.

Also the Bitmap has no field named bData but bitmapData.

One way to get the bitmap from the your sprite is to use the target of the event and use getObjectsUnderPoint to get the bitmap (in case you have multiple bitmap into your sprite)

Also don't forget to take the mouse coordinate from the bmap, otherway you will have to play with Point conversion using globalToLocal and LocalToGlobal

// function to get the bitmap from a display object container
// using the mouse coordinate
function findBitmap(container:DisplayObjectContainer):Bitmap {
 if (container === null)
   return null;

 var childs:Array = container.getObjectsUnderPoint(
    new Point(container.mouseX, container.mouseY)
 );

 while (childs.length > 0) {
   var ret:Bitmap = childs.pop() as Bitmap;
   if (ret !== null)
     return ret;
 }

 return null;
}

// ....
canvas = new Sprite;
addChild(canvas);
canvas.addChild(bmap);
//Mouse Track Pixel Colors
canvas.addEventListener(MouseEvent.CLICK, readPixel);
// ...

function readPixel(e:MouseEvent):void {
    // found the bitmap from the currentTarget
    var bmap:Bitmap=findBitmap(e.currentTarget as DisplayObjectContainer);

    var hex:uint=0;

    if (bmap!==null) {
     hex = bmap.bitmapData.getPixel32(bmap.mouseX, bmap.mouseY); 
    }

    var pixelAlpha:int = (hex >>> 0x18) & 0xff;
    var red:int = (hex >>> 0x10) & 0xff;
    var green:int = (hex >>> 0x08) & 0xff;
    var blue:int = hex & 0xff;

    colorText.text =
         "Red:" + red + " Green:" + green + " Blue:" + blue + " Alpha:" + pixelAlpha;
    }
Patrick
e.currentTarget will be the mc, not the bitmap.
UltimateBrent
@UltimateBrent No since i add the event to the bitmap, but anyway there since Bitmap is not an interactive object i will not get the event, i will modify it.
Patrick
thanks patrick. works perfectly!
TheDarkInI1978
A: 

The problem is that "e" is an event, which doesn't have a bmap property. It will have a target property, but that will be a event dispatcher, in this case your canvas.

I would suggest:

Create a custom class that extends sprite and contains your bitmap. Create an instance of that class and add it to the stage. Add your event listener to that object instead of the stage. In your event listener check that event.target is an instance of your custom class. If so, you can use the event's localX and localY to get the pixel value of the object's bitmap property.

justkevin
+1  A: 

Easiest way is to make your bitmap a property of the canvas so it can easily be referenced from the canvas. The event is firing from the canvas object so e.target will be your canvas. From there, you can hit your bitmap, and the bitmapData property of your bitmap will reference your bitmap data.

function showBitmapData(e:Event):void
    {
    var bData:BitmapData = new BitmapData(video.width, video.height);
    bData.draw(video);

    var bmap:Bitmap = new Bitmap(bData);
    bmap.x = 220;
    bmap.y = 20;
    bmap.scaleX = bmap.scaleY = 2;

    canvas = new MovieClip(); //sprites can't have arbitrary properites
    addChild(canvas);
    canvas.bmap = bmap; //*** Look at me! I can be referenced later!
    canvas.addChild(bmap);

    //Mouse Track Pixel Colors
    canvas.addEventListener(MouseEvent.CLICK, readPixel);
    }

function readPixel(e:MouseEvent):void
    {

    var hex:uint = e.target.bmap.bitmapData.getPixel32(mouseX, mouseY); // e.target is your "canvas" from before
    var pixelAlpha:int = (hex >>> 0x18) & 0xff;
    var red:int = (hex >>> 0x10) & 0xff;
    var green:int = (hex >>> 0x08) & 0xff;
    var blue:int = hex & 0xff;

    colorText.text = "Red:" + red + " Green:" + green + " Blue:" + blue + " Alpha:" + pixelAlpha;
    }
UltimateBrent
i see what you are saying. unfortunately, i can't seem to add any properties to my canvas sprite?! ReferenceError: Error #1056: Cannot create property bmap on flash.display.Sprite.
TheDarkInI1978
also, in my AS3 settings i have "Automatically declare stage instances" turned on. but it's still not letting me add the property.
TheDarkInI1978
Try checking if bmap.name is "bmap". If so, you can do `e.target.getChildByName('bmap').bitmapData.getPix...` instead of bothering with the property. If not, set the name property. Sorry, I was pretty sure you could set arbitrary properties on MCs.
UltimateBrent
Oh, the other option is make `canvas` a `MovieClip`. I didn't realize you were using a sprite.
UltimateBrent
thanks for the replies, UltimateBrent. changing the sprite to the movie clip works, but it's not reading the color data. i've traced the mouseX and mouseY clicks from the readPixel function, so the function is being called at least. it's simply returning 0 for the ARGB vars. one last thing: i'm a bit surprised that i can't assign my own properties to a Sprite but i can to a MovieClip. i thought Sprite was the same thing minus the timeline support. care to elaborate?
TheDarkInI1978
@Chunk1978 i have modify my answer and put a generic function to get the bitmap
Patrick