clanguage-agnosticcolors

Converting color value from float 0..1 to byte 0..255


What would be the correct way of converting color value from float to byte? At first I thought b=f*255.0 should do it, but now I'm thinking, that in this case only the exact 1.0 will be converted to 255, but 0.9999 will already be 254 which is probably not what I want...

It seems that b=f*256.0 would be better except that it would have an unwanted case of making 256 in the case of exact 1.0.

In the end I'm using this:

#define F2B(f) ((f) >= 1.0 ? 255 : (int)((f)*256.0))

Solution

  • 1.0 is the only case that can go wrong, so handle that case separately:

    b = floor(f >= 1.0 ? 255 : f * 256.0)
    

    Also, it might be worth forcing that f really is 0<=f<=1 to avoid incorrect behaviour due to rounding errors (eg. f=1.0000001).

    f2 = max(0.0, min(1.0, f))
    b = floor(f2 == 1.0 ? 255 : f2 * 256.0)
    

    Alternative safe solutions:

    b = (f >= 1.0 ? 255 : (f <= 0.0 ? 0 : (int)floor(f * 256.0)))
    

    or

    b = max(0, min(255, (int)floor(f * 256.0)))