• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Get average brightness of a JPG movieclip?

Contributor ,
Feb 22, 2011 Feb 22, 2011

Copy link to clipboard

Copied

Hi, I was working on a project a few months ago, which I had to put on hold but am finally getting back to. One major feature I need that I wasn't able to figure out before was how to measure the average brightness of an image file loaded as a movieclip. I remember spending hours going through tutorials but I wasn't able to get it working. Now I don't even remember what or where I read before and I'm not keen on rereading all of it and still not knowing what to do.

I just want the simplest possible way to get an average brightness level of an image, I don't care which way the brightness is measured as it is only important relative to other images which will be measured the same way. Any help would be greatly appreciated, thank you.

TOPICS
ActionScript

Views

2.3K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Contributor , Jul 12, 2012 Jul 12, 2012

Coming back to this a year and a half later, I've had to expand the number of images that are being checked, and now the inaccuracy from reading transparent pixels as white is too severe. Anyone know a better way to do this?

EDIT:

How many times did I think I got this right before I actually did? Anyway, HERE IS THE REAL SOLUTION. Less complicated than what I was trying before.

protected static function getAverageColor(image:MovieClip):Number {

                              var bmp:BitmapData = new

...

Votes

Translate

Translate
Community Expert ,
Feb 22, 2011 Feb 22, 2011

Copy link to clipboard

Copied

use the bitmapdata class and loop through its pixels.  you probably only need to check 1/4 or 1/9 the pixels to get an average brightness.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Feb 22, 2011 Feb 22, 2011

Copy link to clipboard

Copied

Ah yeah, that's what I remember messing with before. Well, I'll try it again, but if you've got any more specific advice that'd be great, otherwise I'll just come back if I need more help. Thanks!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Feb 24, 2011 Feb 24, 2011

Copy link to clipboard

Copied

hi

you could also use the histogram() method of BitmapData to get the 'amount' of colour in the image:

var v:Vector.<Vector.<Number>> = myBitmapDataObject.histogram(new Rectangle(...));

this returns a Vector containing 4 Vectors (one for R,G,B and A) which contain 256 items - so it may be quicker to sum and average 3x256 values rather than bitmapWidth x bitmapHeight values (especially as getPixel is relatively slow)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Feb 28, 2011 Feb 28, 2011

Copy link to clipboard

Copied

Thanks Lee, that sounds like a good approach, but I don't know how to use vectors so I don't know how to implement it. Could you explain?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 01, 2011 Mar 01, 2011

Copy link to clipboard

Copied

hi

this should do the trick (assuming you have a BitmapData object called "bmd"):

var v:Vector.<Vector.<Number>> = bmd.histogram(new Rectangle());
var r:Number = 0;
var g:Number = 0;
var b:Number = 0;
for (var i:uint=0;i<256;i++)
{
     r += i*v[0]/255;
     g += i*v[1]/255;
     b += i*v[2]/255;
}
var totalPixels:uint = bmd.rect.width*bmd.rect.height;
r /= totalPixels;
g /= totalPixels;
b /= totalPixels;
var brightness:Number = (r+g+b)/3;

You should now have a value between 0 and 1 for the image brightness (this is off the top of my head so there may be a bug in there somewhere...)

For general info on using Vectors, see: http://www.mikechambers.com/blog/2008/08/19/using-vectors-in-actionscript-3-and-flash-player-10/

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Mar 02, 2011 Mar 02, 2011

Copy link to clipboard

Copied

Thanks Lee, I tried it but the R, G, and B values always return 0. Any thoughts?

EDIT: By removing "new Rectangle()" from the function call I think I got it partly working, but return values range from .75 to 1.

For PNGs with transparency it reads fully transparent pixels as white; guess I can't do anything about that.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 02, 2011 Mar 02, 2011

Copy link to clipboard

Copied

hi

yes - my bad; new Rectangle() should be null (or empty)

make sure your bitmapData object is not transparent (ie: third param of constructor is false)

for transparent bm's, this seems to work (but havent tested thoroughly)

var v:Vector.<Vector.<Number>> = bmd.histogram(null);

var r:Number = 0;

var g:Number = 0;

var b:Number = 0;

var a:Number = 0;

for (var i:uint=0;i<256;i++)

{

     r += i*v[0]/255;

     g += i*v[1]/255;

     b += i*v[2]/255;

     a += i*v[3]/255;

}

var totalPixels:uint = bmd.rect.width*bmd.rect.height;

r /= totalPixels;

g /= totalPixels;

b /= totalPixels;

a /= totalPixels;

var brightness:Number = a*(r+g+b)/3;

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 03, 2011 Mar 03, 2011

Copy link to clipboard

Copied

There is one more trick, instead of all teh calculations. Though i like the idea of the histogram.

Shrink the jpg to 1x1 pixel width.

And check what the color is.  that will give you an average color.

Then you can get the brightness of that rgb by returning the perceived LUMA

     var luma:int =  red * red * .241 +   green * green * .691 +   blue * blue  * .068

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Mar 06, 2011 Mar 06, 2011

Copy link to clipboard

Copied

Lee, is the new variation you game me supposed to ignore alpha? It gives me a slightly different value but it's still reading fully transparent pixels as pure white. It doesn't matter if I set the transparency in the BMD constructor to false or true.

Lazec, that's an interesting idea, I'll try it out. Do you know how reliable it is? I need a completely reliable method for what I'm doing.

EDIT: I just realized I was doing var bmd:BitmapData = new BitmapData(testImage.width,testImage.height,true) but I should have been doing var bmd:BitmapData = new BitmapData(testImage.width/4,testImage.height/4,true). I don't understand why it needs to be that way yet, but that fixes the values only ranging from .75 to 1. It doesn't help with the transparent pixels reading as pure white but maybe it will be less of an issue.

EDIT2: Yeah, after fixing the problem with the dimensions, Lee's method is definitely accurate enough for my purposes, even with the transparency problem. Awesome, thanks again Lee.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Jul 12, 2012 Jul 12, 2012

Copy link to clipboard

Copied

LATEST

Coming back to this a year and a half later, I've had to expand the number of images that are being checked, and now the inaccuracy from reading transparent pixels as white is too severe. Anyone know a better way to do this?

EDIT:

How many times did I think I got this right before I actually did? Anyway, HERE IS THE REAL SOLUTION. Less complicated than what I was trying before.

protected static function getAverageColor(image:MovieClip):Number {

                              var bmp:BitmapData = new BitmapData(image.width,image.height, true, 0x00000000);

                              //bmp.draw(image);

                              bmp.draw(image.getChildAt(0));

                              var v:Vector.<Vector.<Number >  >  = bmp.histogram();

                              var r:Number = 0;

                              var g:Number = 0;

                              var b:Number = 0;

                              var a:Number = 0;

                              for (var i:int=0; i<256; i++) {

                                        r +=  i * v[0] / 255;

                                        g +=  i * v[1] / 255;

                                        b +=  i * v[2] / 255;

                                        a += i*v[3]/255;

                              }

                              var brightness:Number = (r+g+b)/(3*a);

                              bmp.dispose();

                              trace("brightness: " + brightness);

                              return brightness;

                    }

Returns a value between 0 and 1, with .5 being halfway between pure white and pure black.

Message was edited by: xTLS

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines