I'm not sure, but maybe it is.

Your approach seemed the easiest and fastest, so I gave it a try. I'm
getting very different results compared to the other 2 methods, but I'm not
really sure if I'm scaled the image properly, that's why I posted the code.

Anyway, since I already have the code for the 3 methods, I'm pasting it.
(It's quick and dirty timeline code; it only requires a MovieClip with a
src_mc instance placed on stage name to test).

I'm getting this results:

calculateFromScaledBimtap : 50 ms
avgGrey: 0.8941176470588235

calculateFromGreyScale : 140 ms
avgGrey: 0.5459394447722504

calculateFromHLS : 3191 ms
avgGrey: 0.555617495923406


Cheers
Juan Pablo Califano



import flash.filters.ColorMatrixFilter;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.geom.Matrix;
import ColorUtils;

function getGreyFilter():ColorMatrixFilter {
    // luminance coefficients
    const rWeight:Number = 0.212671;
    const gWeight:Number = 0.715160;
    const bWeight:Number = 0.072169;

    var colMatrix:Array = [
                    rWeight,    gWeight,    bWeight,    0,    0,
                    rWeight,    gWeight,    bWeight,    0,    0,
                    rWeight,    gWeight,    bWeight,    0,    0,
                    0,          0,          0,          1,    0
                ];

    return new ColorMatrixFilter(colMatrix);
}

function toGreyScale(src:DisplayObject):BitmapData {
    var dest:BitmapData = new BitmapData(src.width,src.height);
    var greyFilter:ColorMatrixFilter = getGreyFilter();
    dest.draw(src);
    dest.applyFilter(dest,new Rectangle(0,0,src.width,src.height),new
Point(0,0),greyFilter);
    return dest;
}

function getGreyAverageValue(src:DisplayObject):Number {
    var greyBmd:BitmapData = toGreyScale(src);
    var rows:int = greyBmd.height;
    var cols:int = greyBmd.width;

    var accum:int = 0;

    for(var r:int = 0; r < rows; r++) {
        for(var c:int = 0; c < cols; c++) {
            accum += greyBmd.getPixel(c,r) & 0xff; // take just one of the
RGB channels, since they all have the same value

        }
    }
    return accum / (rows * cols);
}

function getAverageFromHLS(src:DisplayObject):Number {

    var dest:BitmapData = new BitmapData(src.width,src.height);
    dest.draw(src);
    var rows:int = dest.height;
    var cols:int = dest.width;

    var accum:Number = 0;

    for(var r:int = 0; r < rows; r++) {
        for(var c:int = 0; c < cols; c++) {
            accum +=  ColorUtils.RGBtoHLS(dest.getPixel(c,r)).l;
        }
    }
    return accum / (rows * cols);

}

function getAverageFromScaledBitmap(src:DisplayObject):Number {
    var dest:BitmapData = new BitmapData(1,1);
    var mat:Matrix      = new Matrix();
    var sx:Number       = 1 / src.width;
    var sy:Number       = 1 / src.height;

    mat.scale(sx,sy);
    dest.draw(src,mat,null,null,null,true);
    var hls:Object = ColorUtils.RGBtoHLS(dest.getPixel(0,0));

    return hls.l;
}

function calculateFromGreyScale(e:MouseEvent):void {

    var initTimer:int = getTimer();
    var avgGrey:Number = getGreyAverageValue(src_mc);
    avgGrey /= 255;
    output_txt.appendText("calculateFromGreyScale : " + (getTimer() -
initTimer) + " ms\n");
    output_txt.appendText("avgGrey: " + avgGrey + "\n\n");


}

function calculateFromHLS(e:MouseEvent):void {
    var initTimer:int = getTimer();
    var avgGrey:Number = getAverageFromHLS(src_mc);
    output_txt.appendText("calculateFromHLS : " + (getTimer() - initTimer) +
" ms\n");
    output_txt.appendText("avgGrey: " + avgGrey  + "\n\n");
}

function calculateFromScaledBimtap(e:MouseEvent):void {
    var initTimer:int = getTimer();

    var avgGrey:Number = getAverageFromScaledBitmap(src_mc);
    output_txt.appendText("calculateFromScaledBimtap : " + (getTimer() -
initTimer)  + " ms\n");
    output_txt.appendText("avgGrey: " + avgGrey  + "\n\n");
}

function createButton():Sprite {
    var btn:Sprite = new Sprite();
    btn.graphics.beginFill(0xff0000);
    btn.graphics.drawRect(0,0,60,60);
    btn.graphics.endFill();
    btn.buttonMode = true;
    return btn;
}


var scaled_btn:Sprite   = createButton();
var grey_btn:Sprite     = createButton();
var hls_btn:Sprite      = createButton();
var output_txt:TextField = new TextField();

output_txt.multiline = true;
output_txt.width = 300;
output_txt.height = 500;

scaled_btn.y    = 0;
grey_btn.y      = 80;
hls_btn.y       = 160;
output_txt.x    = 100;

addChild(scaled_btn);
addChild(grey_btn);
addChild(hls_btn);
addChild(output_txt);

scaled_btn.addEventListener(MouseEvent.CLICK,calculateFromScaledBimtap);
grey_btn.addEventListener(MouseEvent.CLICK,calculateFromGreyScale);
hls_btn.addEventListener(MouseEvent.CLICK,calculateFromHLS);




2009/3/29 Ian Thomas <[email protected]>

> Flash's smoothing may introduce irregularities, I guess.
>
> But given that the original poster only wanted to know grey or white,
> surely it's a good enough approximation for that purpose?
>
> Ian
>
> On Sun, Mar 29, 2009 at 9:08 PM, Juan Pablo Califano
>  <[email protected]> wrote:
> > It's indeed much faster (five times faster than transforming to grey
> scale),
> > though the results I'm getting are incorrect (the other 2 methods seems
> to
> > return consistently similar results, though trasnforming to HLS takes
> about
> > 3200 ms for a 1152 x 864 image, and transform to grey scale takes around
> 130
> > ms).
> >
> > It could be the case that I'm doing it the wrong way, of course... This
> is
> > the code I'm using.
> >
> >
> > function getAverageFromScaledBitmap(src:DisplayObject):Number {
> >    var dest:BitmapData = new BitmapData(1,1);
> >    var mat:Matrix   = new Matrix();
> >    var sx:Number   = 1 / src.width;
> >    var sy:Number   = 1 / src.height;
> >
> >    mat.scale(sx,sy);
> >    dest.draw(src,mat,null,null,null,true);
> >    var hls:Object = ColorUtils.RGBtoHLS(dest.getPixel(0,0));
> >
> >    return hls.l;
> > }
> > Cheers
> > Juan Pablo Califano
> >
> > 2009/3/29 Ian Thomas <[email protected]>
> >
> >> On Sun, Mar 29, 2009 at 8:14 PM, Juan Pablo Califano
> >> <[email protected]> wrote:
> >> > As it's been said already, you could try converting to HLS and the get
> >> the
> >> > average luminance (brigthness). Here's a handy class to convert from
> RGB
> >> to
> >> > HSL and viceversa.
> >> >
> >> > http://www.dreaminginflash.com/2007/11/19/hls-to-rgb-rgb-to-hls/
> >> > Another approach, which might be faster (but you'd have to test it to
> see
> >> if
> >> > that's true), could be transforming to bitmap to a grey scale. You
> would
> >> > then know how black / white each pixel is, so you could get the
> average
> >> > value by adding the value of each pixel and dividing for the total
> number
> >> of
> >> > pixels. Instead of reading the whole pixel value, you can just read
> one
> >> > channel, because since it' s a grey scale, the three color channels
> will
> >> be
> >> > equal.
> >>
> >> If you're going to test any kind of average pixel value, it'd be far
> >> faster to take a bitmap copy of the frame scaled to 1 pixel x 1 pixel
> >> (with smoothing on) - and just read the colour value of that pixel...
> >>
> >> HTH,
> >>   Ian
> >>  _______________________________________________
> >> Flashcoders mailing list
> >> [email protected]
> >> http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
> >>
> > _______________________________________________
> > Flashcoders mailing list
> > [email protected]
> > http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
> >
>
> _______________________________________________
> Flashcoders mailing list
> [email protected]
> http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
>
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Reply via email to