1
votes

Basically, I want to get the most common ARGB value that appears in a BitmapData. That is, I want to know which exact pixel colour is the most abundant in the image. I tried going through every pixel of the image and counting whenever a colour that already exists comes up, but that's way too slow, even with relatively small images. Does anybody know a faster method for this, maybe using the BitmapData.histogram() function or something?

Ideally the process should be near instantaneous for images around at least 1000x1000 pixels.

2
I found a similar question with a good answer, it might help you stackoverflow.com/a/9879812/1123633 - Johan Lindkvist
I've seen that: unfortunately the solution appears to find the average colour, which is not what I'm looking for. I'm looking for the single colour value that appears the most times in an image. Like if you have 20 pixels that are 0xFF89ae00, and 10 that are 0xFFae0089, the resultant colour I would get would be 0xFF89ae00, because that's the colour that most pixels have. - puggsoy
Oh okay i misunderstood the answer (to the one i linked), sorry ^^. - Johan Lindkvist
Are you using getPixel() or getVector()? - NoobsArePeople2
I was using getPixel32(): now I see that getVector() is better for this use, but I hadn't used it before Vesper's answer. - puggsoy

2 Answers

1
votes

Run through bitmapData.getVector() with a Dictionary to hold numbers, then sort that Dictionary's key-value pairs by value and get the key of maximum.

var v:Vector.<uint>=yourBitmapData.getVector(yourBitmapData.rect);
var d:Dictionary=new Dictionary();
for (var i:int=v.length-1; i>=0;i--) {
    if (d[v[i]]) d[v[i]]++; else d[v[i]]=1;
}
var maxkey:String=v[0].toString();
var maxval:int=0;
for (var k:String in d) {
    if (d[k]>maxval) {
        maxval=d[k];
        maxkey=k;
    }
}
return parseInt(maxkey); // or just maxkey
0
votes

I haven't worked with shaders at all, but I think you might be able to get faster results. Looping through pixels is faster at the shader level.

I'd try by creating essentially the same loop in the shader, and paint the entire resulting bitmap with the most used colour and sample that (unless you can get a variable directly out of the shader)

this should be significantly faster