颜色从16转换为32,反之亦然

时间:2013-01-19 23:09:15

标签: c# colors rgb

我正在开发一个游戏客户端,其中纹理颜色存储为int值。然而,有时候,我必须使用16位颜色来绘制一些纹理...所以我想知道如何将32位颜色转换为16位颜色,反之亦然......最好避免像Color.FromArgb()等类似的托管函数。我更喜欢通过字节移位尽快实现这些操作。 你也知道如何获得32位颜色的灰度值吗?

1 个答案:

答案 0 :(得分:1)

    public static Int32 16To32(UInt16 color)
    {
        Int32 red = (Int32)(((color >> 0xA) & 0x1F) * 8.225806f);
        Int32 green = (Int32)(((color >> 0x5) & 0x1F) * 8.225806f);
        Int32 blue = (Int32)((color & 0x1F) * 8.225806f);

        if (red < 0)
            red = 0;
        else if (red > 0xFF)
            red = 0xFF;

        if (green < 0)
            green = 0;
        else if (green > 0xFF)
            green = 255;

        if (blue < 0)
            blue = 0;
        else if (blue > 0xFF)
            blue = 0xFF;

        return ((red << 0x10) | (green << 0x8) | blue);
    }

    public static UInt16 32To16(Int32 color)
    {
        Int32 red = ((((color >> 0x10) & 0xFF) * 0x1F) + 0x7F) / 0xFF;
        Int32 green = ((((color >> 0x8) & 0xFF) * 0x1F) + 0x7F) / 0xFF;
        Int32 blue = (((color & 0xFF) * 0x1F) + 0x7F) / 0xFF;

        return (UInt16)(0x8000 | (red << 0xA) | (green << 0x5) | blue);
    }

关于grayscaling的问题...你可以尝试以下功能,但我只是在没有测试的情况下编写它,所以我无法保证它能完美运行:

    public static Int32 Grayscale(Int32 color)
    {
        Single red = ((color >> 0xA) & 0x1F) * 8.225806f;
        Single green = ((color >> 0x5) & 0x1F) * 8.225806f;
        Single blue = (color & 0x1F) * 8.225806f;

        Int32 grayscale = (Int32)(((red * 0.299f) + (green * 0.587f) + (blue * 0.114f)) * 0.1215686f);

        if (grayscale < 0)
            grayscale = 0;
        else if (grayscale > 0x1F)
            grayscale = 0x1F;

        return grayscale;
    }