Calculate the average color of an image I want to calculate the average color+opacity of an image. First I thought about just averaging all ARGB values component-wise, but this got really dark on images with a lot of transparency. I also don't think mixing RGB colors is a good idea in general since they are nonlinear due to Gamma or something. I also had a look at HSV/HSB but this seems a pretty stupid idea.

So, what is a reasonably physically correct way to average the color of an ARGB image? I prefer solutions in Java and using 8 bit per color channel. The solution should also take care that the image may have an arbitrary amount of transparent or semi-transparent pixels.
Averaging RGB should be correct assuming you do it in linear RGB. If your images are in sRGB, you can remove the gamma correction by doing something like the following for each of the R, G, and B components:

float sRGBToLinear(UInt8 component)
{
    float tempComponent = (float)component / 255.0;
    if (tempComponent &lt;= 0.04045)
    {
        tempComponent = tempComponent / 12.92;
    }
    else
    {
        tempComponent = pow((tempComponent + 0.055) / (1.055), 2.4);
    }
    return tempComponent;
}


You can then average together all of the red values in the image, all of the green values in the image, and all of the blue values in the image after they've been run through the above conversion. You can then do the opposite conversion to get back to sRGB:

UInt8 linearRGBTosRGB(float component)
{
    float tempComponent =  0.0;
    if (component &lt;= 0.00318308)
    {
        tempComponent = 12.92 * component;
    }
    else
    {
        tempComponent = 1.055 * pow(component, 1.0 / 2.4) - 0.055;
    }
    return (UInt8)(tempComponent * 255.0);
}


(My apologies if I've messed up the syntax. I'm a C/C++ programmer and don't know the intricacies of Java.)

Note that alpha makes things slightly more complicated. If you're using premultiplied alpha, you can simply apply the above calculations for the average. If you're using straight alpha, you'll want to multiply each of the R, G, and B components by the alpha before doing the averaging.