0
\$\begingroup\$

Particularly, how do you implement Color.GetBrightness (?)

public static bool isDark(Texture2D tex,float threshold=0.1f)
    { 
        float sum = 0 ;
        for (int x = 0; x < tex.width; x++)
        {
            for (int y = 0; y < tex.height; y++)
            {
                sum += GetBrightness(tex.GetPixel(x, y));
            }
        }
        sum /= (int)(tex.width*tex.height);

        if (sum < threshold) return false;
        return true;
    }
    static float GetBrightness(Color color)
    {
        return (color.r + color.b + color.g) / 3f; 
    }
\$\endgroup\$
1
  • 2
    \$\begingroup\$ I think the answer would depend on why exactly you are doing this. What are you going to use that "Brightness" value for? \$\endgroup\$
    – Philipp
    Jan 16, 2022 at 11:22

2 Answers 2

0
\$\begingroup\$

Dark and Light is a subjective feeling. First of all you'd need to define what you want to consider dark, or light.

Once you have that defined, start calculating.

First of all, I would not just add all components and divide them. Here is a simple example (For simplicity I go with ints, though it is the same for floats:

r:100 b:100 g:100 = 300 / 3 = 100

r:250 b:50 g:0 = 300 / 3 = 100

As you can see it is not as simple as taking all three channels.

What I would do instead is define a brightness factor per channel: e.g. red might not feel as bright as green. Then take this factors and calculate the amount.

This could be as simple as r * 1.0 g * 1.3 b * 0.7 / 3

The complexity is up to you.

Another (rather dumb) way is taking all channels and just adding them. Define threshold of say 400 is bright. Then r:255 + g:105 :b:0 = 360 Not bright r:255 + g:255 :b:50 = 560 Bright

\$\endgroup\$
8
  • \$\begingroup\$ would you use a histogram? \$\endgroup\$
    – ina
    Jan 16, 2022 at 10:01
  • \$\begingroup\$ @ina You certainly can! You don't have to though. It is up to you how accurate you want the calculation to be. If you feel like it is the right choice, just go for it. There will very unlikely be any issues with that \$\endgroup\$ Jan 16, 2022 at 10:03
  • \$\begingroup\$ what's the best way? \$\endgroup\$
    – ina
    Jan 16, 2022 at 10:04
  • 1
    \$\begingroup\$ There is no best way, it really comes down to your needs. If you just want a rough estimate a simple calculation such as the ones in my answer is enough. If you need it very detailed, a histogram can certainly help \$\endgroup\$ Jan 16, 2022 at 10:16
  • \$\begingroup\$ would this be easier to determine if the image is converted to grayscale first, to not worry about rgb? \$\endgroup\$
    – ina
    Jan 16, 2022 at 10:27
0
\$\begingroup\$

A conventional way to determine the lightness of a colour is to compute its relative luminance for linear RGB data, or luma, if the colours you're working with are in gamma-compressed encoding (as is typically the case for textures).

Assuming your image is in sRGB format (gamma-compressed, ITU-R BT.709 colour primaries and white point), you'd implement this like so, using the colour coefficients from the links above:

static float GetLuma(Color color) {
    // Rec. 709 colour primaries.
    const float r = 0.2126f;
    const float g = 0.7152f;
    const float b = 0.0722f;

    return color.r * r + color.g * g + color.b * b;
}

You can make your categorization function a little faster by using one call to GetPixels() instead of many calls to GetPixel():

public static bool IsDark(Texture2D tex, float threshold=0.1f)
{ 
    float sum = 0;
    var pixels = tex.GetPixels();
    foreach (var pixel in pixels)
        sum += GetLuma(pixel);

    sum /= pixels.Length;

    return sum >= threshold;
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .