【问题标题】:Converting a number to a colour将数字转换为颜色
【发布时间】:2014-03-23 21:03:14
【问题描述】:

我正在尝试将整数(0 到 65536)转换为 C# 中的 Color 对象。最初,我想创建一个所有可能的 16 位颜色的列表,并用整数对其进行寻址,但这非常低效。

如何获得第 i 个可能的 16 位颜色对象?

【问题讨论】:

  • 首先您需要定义 ushort 和颜色之间的映射。哦,当然你的意思是 65535。
  • 那么,您的寻址方案是什么?那是 16 位 调色板 吗?还是那是 3x5 位 RGB?还是 4x4 位 RGBA?要么...?如果是调色板,那么我们不知道颜色[u]是什么:需要单独定义。 16 位调色板可以引用 32 位颜色[u]r 集。
  • 我正在尝试使用16 bit high colour。简而言之,我的逻辑是:如果我要生成所有可能的 16 位颜色,按顺序,在 i 点会出现什么颜色?

标签: c# math colors logic base


【解决方案1】:

16 位颜色通常由 5 位红色、6 位绿色和 5 位蓝色组成:

rrrr rggg gggb bbbb

参考:Wikipedia: High color

要将其转换为 Color 结构所表示的 24 位颜色,您需要提取颜色分量并将它们转换为 0..255 范围:

int red = color >> 11;
int green = (color >> 5) & 63;
int blue = color & 31;

red = red * 255 / 31;
green = green * 255 / 63;
blue = blue * 255 / 31;

Color result = Color.FromArgb(red, green, blue);

【讨论】:

    【解决方案2】:

    .NET Color 结构以 32 位 存储颜色。

    您需要知道您的 16 位颜色是如何编码的:

    • R5 G6 B5(红色 5 位,绿色 6 位,蓝色 5 位)
    • A1 R5 G5 B5(1 位用于 alpha)
    • 任何其他编码

    假设您的 16 位颜色是 A1 R5 G5 B5

    目标将是A8 R8 G8 B8

    public static Color FromUInt16(UInt16 color)
    {
        Int32 fullColor = color;
    
        Int32 maskA = 32768;    // binary 1 00000 00000 00000
        Int32 maskR = 0x7C00;   // binary 0 11111 00000 00000
        Int32 maskG = 0x3E0;    // binary 0 00000 11111 00000
        Int32 maskB = 0x1F;     // binary 0 00000 00000 11111
    
        // Mask the whole color with bitmasks to isolate each color.
        // for example : 1 11111 11111 11111 (white) masked 
        //with 0 11111 00000 00000 (red) will give : 0 11111 00000 00000
        Int32 alpha =  ((maskA & fullColor) >> 8);
        Int32 red = ((maskR & fullColor) >> 7);
        Int32 green = ((maskG & fullColor) >> 2);
        Int32 blue = ((maskB & fullColor) << 3);
    
        // 1 bit alpha encoding.
        // if   alpha = 1
        // then alpha = 11111111
        // else alpha = 00000000
        alpha = alpha > 0 ? 255 : 0;
    
        // Since the original resolution for each color is 5 bits,
        // and the new resolution is 8 bits, the 3 least significant bits 
        // must be padded with 1's if the 5th bit is 1, otherwise pad them with 0.
        red = (red & 0x8) == 0x8 ? red | 0xF : red;
        green = (green & 0x8) == 0x8 ? green | 0xF : green;
        blue = (blue & 0x8) == 0x8 ? blue | 0xF : blue;
    
        return Color.FromArgb(alpha,red,green,blue);
    }
    

    【讨论】:

    • 这是一个很棒的答案,但我确实有一个问题。我看到 PNG 本身就是 16 位彩色图像,这在图像属性中可见。有没有办法像这样保存图像?
    • 你到底是什么意思?要将整个图像保存为 PNG 吗? PNG 不仅将图像编码为 16 位,而且还对其进行压缩,而压缩是一个复杂得多的主题。
    • 嗯,例如,here's a PNG 以 8 位颜色保存。如果我理解正确,您可以将该图像存储为位深度 16,并且图像将保持不变,但会大两倍。当数据为 16 时,我是否通过将其保存为 24 位深度来浪费空间或歪曲我的输出?
    • 是的,这将是一种浪费,因为这些新位不会在图像中添加任何信息,它们只会复制现有信息(就像我在 3 个最低有效位上填充 1 所做的那样)。这就像拉伸一件衣服。你会让它变大,但绝不会有更多的织物。也就是说,理论上。在实践中,也许 PNG 算法会对颜色或其他类似的东西进行一些平滑处理,这实际上会改变图像中包含的信息。
    猜你喜欢
    • 2013-01-14
    • 1970-01-01
    • 2019-11-14
    • 2019-02-08
    • 2012-05-01
    • 2020-01-16
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多