10

I have an image (mx) and i want to get the uint of the pixel that was clicked.

Any ideas?

Theo
  • 131,503
  • 21
  • 160
  • 205
Cameron A. Ellis
  • 3,833
  • 8
  • 38
  • 46

3 Answers3

10

A few minutes on the BitmapData LiveDoc Page will take you where you need to go. Once you have your image loaded into a Bitmap variable, you can access its BitmapData property. Add a Mouse Click Event Listener to the image and then use BitmapData::getPixel. The example for getPixel shows how to convert the uint response to an rgb hex code.

Here's a modification of the Example given on the BitmapData page that worked for me (using mxmlc - YMMV):

package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;

    public class BitmapDataExample extends Sprite {
        private var url:String = "santa-drunk1.jpg";
        private var size:uint = 200;
        private var image:Bitmap;

        public function BitmapDataExample() {
            configureAssets();
        }

        private function configureAssets():void {
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);

            var request:URLRequest = new URLRequest(url);
            loader.load(request);
            addChild(loader);
        }

        private function completeHandler(event:Event):void {
            var loader:Loader = Loader(event.target.loader);
            this.image = Bitmap(loader.content);

            this.addEventListener(MouseEvent.CLICK, this.clickListener);
        }

        private function clickListener(event:MouseEvent):void {
            var pixelValue:uint = this.image.bitmapData.getPixel(event.localX, event.localY)
            trace(pixelValue.toString(16));
        }
    }
}
enobrev
  • 22,314
  • 7
  • 42
  • 53
8

Here's an even simpler implementation. All you do is take a snapshot of the stage using the draw() method of bitmapData, then use getPixel() on the pixel under the mouse. The advantage of this is that you can sample anything that's been drawn to the stage, not just a given bitmap.

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.*;

stage.addEventListener(MouseEvent.CLICK, getColorSample);

function getColorSample(e:MouseEvent):void {
    var bd:BitmapData = new BitmapData(stage.width, stage.height);
    bd.draw(stage);
    var b:Bitmap = new Bitmap(bd);
    trace(b.bitmapData.getPixel(stage.mouseX,stage.mouseX));
}

Hope this is helpful!


Edit:

This edited version uses a single BitmapData, and removes the unnecessary step of creating a Bitmap. If you're sampling the color on MOUSE_MOVE then this is essential to avoid memory issues.

Note: if you're using a custom cursor sprite you'll have to use an object other than 'state' or else you'll be sampling the color of the custom sprite instead of what's under it.

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.*;

private var _stageBitmap:BitmapData;

stage.addEventListener(MouseEvent.CLICK, getColorSample);

function getColorSample(e:MouseEvent):void 
{
    if (_stageBitmap == null) {
        _stageBitmap = new BitmapData(stage.width, stage.height);
    }
    _stageBitmap.draw(stage);

    var rgb:uint = _stageBitmap.getPixel(stage.mouseX,stage.mouseY);

    var red:int =  (rgb >> 16 & 0xff);
    var green:int =  (rgb >> 8 & 0xff);
    var blue:int =  (rgb & 0xff);

    trace(red + "," + green + "," + blue);
}
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
defmeta
  • 1,322
  • 3
  • 11
  • 19
  • I AM GOING TO KILL YOU !!!!!!!!!!! Can anybody see why.... ;-) Tip: Always double check stackoverflow code before using it :-) – Simon_Weaver Apr 08 '11 at 23:12
  • I'd throw in some simple bounds checking for good measure, to make sure you catch when your x and y are outside of the stage area. – Adam Smith Apr 27 '11 at 15:02
  • 1
    You don't need to draw the entire stage just to grab one pixel value. Make the BitmapData 1x1 and pass a matrix and a clipRect to that draw call. – darscan Dec 23 '11 at 18:32
8

This is not specific to Flex or mx:Image, and allows you to grab a pixel color value from any bitmap drawable object (provided you have permission):

private const bitmapData:BitmapData = new BitmapData(1, 1);
private const matrix:Matrix = new Matrix();
private const clipRect:Rectangle = new Rectangle(0, 0, 1, 1);

public function getColor(drawable:IBitmapDrawable, x:Number, y:Number):uint
{
    matrix.setTo(1, 0, 0, 1, -x, -y)
    bitmapData.draw(drawable, matrix, null, null, clipRect);
    return bitmapData.getPixel(0, 0);
}

You could easily grab a pixel from the stage or your mx:Image instance. It's a lot more efficient than drawing the entire stage (or drawable object), and should be fast enough to hook up to MouseEvent.MOUSE_MOVE for instant visual feedback.

darscan
  • 963
  • 1
  • 12
  • 17
  • 1
    IMO this is definitely the superior answer due to the fact that it doesn't draw the entire stage and more precisely answers the question. – Allar May 30 '12 at 22:04