【问题标题】:How to represent 18bit color depth to 16bit color depth?如何将 18 位色深表示为 16 位色深?
【发布时间】:2009-06-29 06:45:23
【问题描述】:

我正在移植一个从 16 位色深到 18 位色深的软件。如何将 16 位颜色转换为 18 位颜色?谢谢。

【问题讨论】:

标签: c++ graphics bitmap


【解决方案1】:

在不了解设备的情况下,我只能推测。设备通常是红色、绿色、蓝色,因此每种颜色会有 6 位的变化。这意味着每种颜色有 64 种变体,总共有 262,144 种颜色。

任何位图都可以缩放到此显示。如果你取每个分量(比如红色),对其进行归一化,然后乘以 64,你将得到缩放后的版本。

如果您有其他问题或想了解更多详细信息,请询问。

更新:
有两种 16 位位图格式。一个是 5-5-5(每像素 5 位),另一个是 5-6-5(绿色得到一个额外的位)。为了进行这种转换,我假设为 5-5-5。

对于每个像素中的每种颜色,您需要这样的东西:

NewColor = (oldColor/32.0)*64

这会将旧颜色转换为 0.0 到 1.0 之间的数字,然后将其放大到新的值范围。

【讨论】:

  • 您好,先生,感谢您提供的信息。如何将位图的 16 位表示转换为 18 位表示?
  • 如果我们评论的答案是正确的,那意味着我们只会得到 4 位红色 :(
  • 那行得通,有点。不过,你所有的颜色都会变暗。您需要插入值(请参阅我的答案)。
  • 其实颜色会变深一点,绿一点哈哈
  • GMan,无法正确缩放颜色。一切都会变得不那么饱和。
【解决方案2】:

假设16bit颜色为5-6-5格式:

// RRRRR-GGGGGG-BBBBB, 16bit -->

//RRRRR0-GGGGGG-BBBBB0, 18bit with the formula below:
Color18 = ((Color16 & 0xF800) << 2) | ((Color16 & 0x07E0) << 1) | ((Color16 & 0x1F) << 1);

【讨论】:

  • Color18 = ((Color16 & 0xf800) + Color16)
  • @Accipitridae,我想明确(是吗?,无论如何:)我如何选择 R-G-B 值以及如何转换它们。但也许我也应该发布该公式的较短版本。感谢您提及。
【解决方案3】:

我没有在其他答案中看到这一点,但是您希望从 5 位到 6 位的转换能够使二进制 11111 映射到 111111,因为两者都代表 full on。一种方法是复制前导位。

red6 = (red5 << 1) | (red5 >> 4);

如果您使用算术转换,请记住最大值是 31 和 63,而不是 32 和 64。

red6 = (red5 * 63 + 15) / 31; // all ints, +15 is for rounding

如果您关心其他中间值,例如如果您想要 16 映射 32,则可以调整公式(例如,将 15 更改为 14)或只是制作一个表格。

【讨论】:

    【解决方案4】:

    回答转化问题

    我不熟悉 c++ 图像库,但我确信这段代码已经存在于某个地方。但如果你愿意,你可以自己做。

    每个像素都有三个通道:红色、绿色和蓝色。在 16 位位图中,每个通道的每个通道的位数不同。通常,绿色首先获得任何额外的位,因为人眼对该颜色最敏感。

    大概是 565 -- 5 代表红色,6 代表绿色,5 代表蓝色。

    对于 18 位位图(如前所述),每个通道有 6 位。所以绿色很容易!只需将值从 16 位格式复制到 18 位格式。其他两个通道稍微难一些。你必须从 5 到 6 进行插值:

    18_Value = (16_Value / 32) * 64 //integers only of course.  You need to round properly to get best results.
    

    你有它。如果您还不熟悉以下内容,我建议您研究一下:

    • 位移运算符
    • 位图步幅
    • 指针数学
    • 字节对齐

    --编辑-- 确保你知道事物在内存中是如何布局的; RGB 或 BGR。如果您做的事情比这更复杂,并且您正在向后考虑它,它会弄乱您的头脑(因为绿色在中间,它对于这种转换并不那么重要)。

    【讨论】:

    • 哇,谢谢,你能举出更多这种转换的例子吗,我对这个东西还很陌生。谢谢。
    • 作为整数除法,这将在每一步钳制一个整数,从而使数字倾斜很多。 63、62、61 和 60 都以相同的颜色结束。
    • 另外,不能除以 5 再乘以 6。这就是位数。您必须乘以和除以它们的数值(十进制的 32 和 64)。
    • 是的,我的意思只是粗略的伪代码。值应适当四舍五入。我会把它添加到答案中。
    • 在除法之前使用 32 位整数进行计算和相乘不是更好吗? (或使用双打?)
    【解决方案5】:

    您首先必须访问每个颜色分量(即提取 R 值、G 值和 B 值)。执行此操作的方式将完全取决于颜色在内存中的存储方式。如果它存储为 RGB,组件有 5-6-5 位,您可以使用如下内容:

    blueComponent  = (colour & 0x1F);
    greenComponent = (colour >> 5 ) & 0x3F;
    redComponent   = (colour >> 11) & 0x1F;
    

    这将为您提取颜色分量,然后您可以使用上述方法转换每个分量(我假设 18 位每个分量将使用 6 位):

    blueComponent  = (blueComponent  / 32.0) * 64;
    //greenComponent = (greenComponent / 64.0) * 64;    // not needed
    redComponent   = (redComponent   / 32.0) * 64;
    

    请注意,对于上面的代码,使用 32.0 或其他确保程序将数字表示为浮点数的方法很重要。然后将组件组合成 18 位颜色,使用:

    colour = (redComponent << 12) | (greenComponent << 6) | blueComponent;
    

    【讨论】:

      猜你喜欢
      • 2011-01-30
      • 2011-04-23
      • 1970-01-01
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多