如何将18位色深表示为16位色深?

时间:2009-06-29 06:45:23

标签: c++ graphics bitmap

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

5 个答案:

答案 0 :(得分: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之间的数字,然后将其缩放到新的值范围。

答案 1 :(得分:1)

假设16位颜色为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);

答案 2 :(得分:1)

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

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

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

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

如果您关心其他中间值,例如您希望16映射32调整公式(例如,更改15到14)或只是制作一个表。

答案 3 :(得分:0)

回答转换问题

我不熟悉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.

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

  • 位移操作符
  • Bitmap Stride
  • 指针数学
  • 字节对齐

- Edit-- 确保你知道记忆中的事情是如何布置的; RGB或BGR。如果你做了比这更复杂的事情并且你正在向后思考它会弄乱你的头(因为格林在中间它不是 对于这种转换很重要。)

答案 4 :(得分:0)

首先,您必须访问每个颜色分量(即提取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;