FromArgb vs FromScRgb

前端 未结 4 1981
花落未央
花落未央 2020-12-20 07:43

Should these two expressions result in colors which are roughly the same?

Color.FromArgb(255, 255, 255, (byte)0.25 * 255))

Color.FromScRgb(1.0f, 1.0f, 1.0f,         


        
相关标签:
4条回答
  • 2020-12-20 08:15

    Same answer as already mentioned - they do not map linearly ( they are different colour spaces - ScRGB is not SRGB with higher precision )

    To mzzzzb "@FurqanSafdar the solution you have given may be correct. but thats not the point here, the thing is that -- intuitively we assume them to be linearly related. btw how did you get to that solution"

    ( We all know what assume does. ) Perhaps it would have been better to link to the definitions of sRGB and ScRGB ! Also, given that they are different color spaces with different ranges, why would you assume ?

    You can see the source code and what is being performed:

    FromScRGB

    FromArgb

    In particular the conversion functions:

    ScRgbTosRgb

    sRgbToScRgb

    The ScRgbTosRgb function is the ColorFloatToByte mentioned by Furqan Safdar.

    0 讨论(0)
  • 2020-12-20 08:20

    from the docs i can see that the last argument is actually the blue component that you are modifying, alpha is same; fully opaque for both colors

    (byte) 0.25 * 255 will give you 0 blue for 0.25 is cast to byte before multiplication, so first one is effectively RGB(255, 255, 0) which is pure yellow. you ought to do (byte) (0.25 * 255) which will be RGB(255, 255, 63)

    when took the second color to paint i found out that it is actually RGB(255, 255, 140). so it seems that the scale 0.0 - 1.0 does not map linearly to 0 - 255.

    0 讨论(0)
  • 2020-12-20 08:24

    Try to use ColorFloatToByte method to have your desired results:

    private static byte ColorFloatToByte(float val)
    {
        if (!(val > 0.0)) // Handles NaN case too
            return (0);
        else if (val <= 0.0031308)
            return ((byte)((255.0f * val * 12.92f) + 0.5f));
        else if (val < 1.0)
            return ((byte)((255.0f * ((1.055f * 
                   (float)Math.Pow((double)val, (1.0 / 2.4))) - 0.055f)) + 0.5f));
        else
            return (255);
    }
    

    Usage:

    Color.FromArgb(255, 255, 255, ColorFloatToByte(0.25f)))
    
    Color.FromScRgb(1.0f, 1.0f, 1.0f, 0.25f))
    
    0 讨论(0)
  • 2020-12-20 08:26

    The basic reason behind this is mentioned by mzzzzb above:

    the scale 0.0 - 1.0 does not map linearly to 0 - 255

    I.e. the ScRgb components do not map linearly to the Argb components.

    0 讨论(0)
提交回复
热议问题