2

8 位色深有 256 种颜色。24 位色深有 16,777,216 种颜色。8 位空间中的每种颜色与 24 位空间中的颜色之间是否存在直接映射?我认为这个问题的答案是肯定的,但对这个答案的评论表明映射只是一个近似值。

我想做的是通过指定 24 位 RGB 值在 24 位颜色空间中创建一个 8 位颜色的调色板。我想我可以使用这个(显然是坏的)逻辑来做到这一点:

红色的 3 位 == 红色的 8 个唯一值,0-7

绿色的 3 位 == 绿色的 8 个唯一值,0-7

蓝色的 2 位 == 蓝色的 4 个唯一值,0-3

255/8 = 32 红色和绿色增量值

255/4 = 64 蓝色增量值

{
    "Red": [0,31,63,95,127,159,191,223,255],
    "Green": [0,31,63,95,127,159,191,223,255],
    "Blue": [0,63,127,191, 255]
}

因此,对于 9 个红色值、9 个绿色值和 5 个蓝色值,我得到 405 种颜色,这是错误的。我知道我需要 8 个红色和绿色值以及 4 个蓝色值,所以我只是稍微调整了一下:

255/ 8 7 = 36.57142857142857 红色和绿色增量值

255/ 4 3 = 85 蓝色增量值

所以这适用于蓝色,但现在我的红色和绿色增量值不是整数。

一旦我弄清楚了映射,我将像这样循环遍历它:

for(r in rgbData.get("Red")) {
    for(g in rgbData.get("Green")) {
        for(b in rgbData.get("Blue")) {
            colors.add("rgb ${r} ${g} ${b}")
        }
    }
}

这可能是一种完全不正确的方法来做我想做的事,只是想表明我已经尝试过一些东西:)

更新:

我尝试了@Marc B 建议的方法,但似乎不对。例如,我生成的地图中没有白色(255, 255, 255使用 24 位 RGB)。使用他的方法这对我来说很有意义,因为224, 224, 192可以看出最高的 RGB 值:

全红 == 111

111 >> 5 == 11100000

全绿 == 111

111 >> 5 == 11100000

全蓝 == 11

11 >> 6 == 11000000

11100000 11100000 11000000 == 224, 224, 192

224, 224, 192 !=白色

这是使用他的方法生成的地图:

{
    "Red": [0,32,64,96,128,160,196,224],
    "Green": [0,32,64,96,128,160,196,224],
    "Blue": [0,64,128,192]
}

以及它生成的调色板:

在此处输入图像描述

更新 2:

在做了更多研究之后,我意识到当“X 颜色”(X 是一些数字,如 256、16,777,216 等)被提及时,这些颜色几乎可以是任何颜色。没有预定义的 256 色集是“该”256 色,尽管有(正如一些已经提到的)预定义的 256 色集是“该”256 色的特定实现。我还能够.gpl在我的组织 wiki 上找到一个 GIMP 调色板文件,它指定了我关心的 256 种颜色,所以我可以从那里复制这些值。

4

3 回答 3

2

实际的答案可能是肯定的。话虽如此,这确实是硬件依赖的事情。@Marc B 接近正确(对于大多数人来说可能足够接近),但真正的答案是它取决于,它取决于硬件,并且从(硬件)实现到实现不会是精确的,但它可能足够精确大多数人。

于 2013-07-18T16:35:02.757 回答
1

转换的方法是将每个通道乘以您想要输出的最高级别,然后除以输入的最高级别。

{
    "Red": [0,36,72,109,145,182,218,255],
    "Green": [0,36,72,109,145,182,218,255],
    "Blue": [0,85,170,255]
}

使用这种方法,您不需要为每个通道分配偶数位,您可以为每个通道使用任意数量的级别。您可以获得更均匀的分布,但不能使用所有 256 种颜色。一种常见的排列是 6/7/6 用于 252 种颜色:

{
    "Red": [0,51,102,153,204,255],
    "Green": [0,42,85,127,170,212,255],
    "Blue": [0,51,102,153,204,255]
}
于 2013-07-18T18:30:54.177 回答
1

我知道这个答案可能有点晚了,但它可能对其他人有用。如果有人知道下面概述的算法叫什么,请在评论中告诉我。

我目前正在使用不同的显示硬件,并且遇到了将具有 m 位的通道转换为具有 n 位的通道的问题,其中 m < n; 例如:将 5 位通道转换为 8 位通道。白色 ( b11111) 应映射到白色 ( b11111111),黑色应映射到黑色。

例如,为了将 5 位映射b10111到 8 位,我用原始数据中的 MSB 填充缺失的位:

b10111
 ^^^--- we need these three MSB again later, as 8-5 = 3 missing bits

左移 3 位:

b10111000

并用 MSB 填充:

b10111101
      ^^^--- the MSBs

这映射得很好(您可能希望对并非全部为1s 的值应用舍入)往返(您可以将少于 8 位转换为 8 位,再转换回来,结果与原始值相同)。

如果较窄的通道小于 4 位宽(如 3),则整个值将完全重复:

b101 -> b10110110
于 2014-08-27T08:12:41.750 回答