2011-12-20 122 views
1

我有一个16位的位图图像,每一种颜色代表一个短的(2字节),我需要在32位位图上下文中显示。如何在C++中将2字节的颜色转换为4字节的颜色?转换16bit颜色为32bit

输入格式在单个短(2字节)中包含每种颜色。

输出格式是32位RGB。这意味着每个像素都有3个字节,我相信?

我需要将短的值转换成RGB颜色。

请原谅我对颜色的认识不足,这是我第一次进入图形编程领域。

+0

你在iOS上用C++做什么?只需使用UIImage或cocos2d。 – 2011-12-20 17:22:49

+0

您提到了三种不同的源格式:每像素16位,每种颜色2个字节,以及“单字节颜色”。这是什么? – interjay 2011-12-20 17:26:27

+1

取决于按位格式... 565/555/556/655等 – tenfour 2011-12-20 17:30:18

回答

3

常用格式包括BGR0, RGB0,0RGB,0BGR。在下面的代码中,我假设了0RGB。改变这个 很容易,只要修改最后一行的移位量即可。

unsigned long rgb16_to_rgb32(unsigned short a) 
{ 
/* 1. Extract the red, green and blue values */ 

/* from rrrr rggg gggb bbbb */ 
unsigned long r = (a & 0xF800) >11; 
unsigned long g = (a & 0x07E0) >5; 
unsigned long b = (a & 0x001F); 

/* 2. Convert them to 0-255 range: 
There is more than one way. You can just shift them left: 
to 00000000 rrrrr000 gggggg00 bbbbb000 
r <<= 3; 
g <<= 2; 
b <<= 3; 
But that means your image will be slightly dark and 
off-colour as white 0xFFFF will convert to F8,FC,F8 
So instead you can scale by multiply and divide: */ 

r = r * 255/31; 
g = g * 255/63; 
b = b * 255/31; 
/* This ensures 31/31 converts to 255/255 */ 

/* 3. Construct your 32-bit format (this is 0RGB): */ 
return (r << 16) | (g << 8) | b; 

/* Or for BGR0: 
return (r << 8) | (g << 16) | (b << 24); 
*/ 
} 
1

乘以三(四,当你有一个alpha层)的16个值 - 这是它:)

你有一个16位彩色,并希望使其成为32位色。这给你四位四位,你想要转换成四位八位。您要添加四位数,但您应该将它们添加到值的右侧。为此,将它们移位四位(乘以16)。此外,您可以通过添加8(您添加4位,其值为0-15,并且您可以取8的平均值进行补偿)补偿一点不准确性。

更新这只适用于每个通道使用4位的颜色并具有Alpha通道。

+1

此解决方案有点幼稚 - 它会留下黑色黑色,但白色会变成灰色。 – 2011-12-20 17:39:04

+0

@CarlNorum正如我所说,你总是在编造数据。没有完美的解决方案。 – 2011-12-20 17:41:31

+0

你总是可以尝试弥补*好*的信息。在这种情况下,事实上,有一个保证最小的错误解决方案 - 请参阅我的答案。 – 2011-12-20 17:47:04

8

通常,16位像素是5位红色,6位绿色和5位蓝色数据。最小误差的解决方案(即,对于其输出的颜色是保证尽可能接近匹配于输入配色)是:

red8bit = (red5bit << 3) | (red5bit >> 2); 
green8bit = (green6bit << 2) | (green6bit >> 4); 
blue8bit = (blue5bit << 3) | (blue5bit >> 2); 

要了解为什么这个解决方案的工作,让我们来看看在红色像素。我们的5位红色是一些分数fivebit/31。我们想把它翻译成新的分数eightbit/255。一些简单的算术题:

 fivebit eightbit 
    ------- = -------- 
     31  255 

产量:

 eightbit = fivebit * 8.226 

或相近(注意是波浪≈):

 eightbit ≈ (fivebit * 8) + (fivebit * 0.25) 

提示操作是由8乘法和4 Owch一个鸿沟 - 这两种操作可能需要永远在您的硬件上。他们两个两个大国和幸运的事情可以转化为移位操作:

 eightbit = (fivebit << 3) | (fivebit >> 2); 

同样的步骤对绿色工作,其中有每像素六位,但你得到一个相应的不同的答案,当然!记住这个解决方案的快速方法是从“短”像素中取出最高位,并在底部添加它们以制作“长”像素。对于需要映射到更高分辨率空间的任何数据集,此方法同样适用。一对夫妇的简单的例子:

five bit space   eight bit space  error 
    00000     00000000     0% 
    11111     11111111     0% 
    10101     10101010    0.02% 
    00111     00111001    -1.01% 
0

还有一些关于模型的问题就像HSV,RGB? 如果你想准备好,开火,瞄准我会先试试这个。

#include <stdint.h> 

uint32_t convert(uint16_t _pixel) 
{ 
    uint32_t pixel; 
    pixel = (uint32_t)_pixel; 
    return ((pixel & 0xF000) << 16) 
     | ((pixel & 0x0F00) << 12) 
     | ((pixel & 0x00F0) << 8) 
     | ((pixel & 0x000F) << 4); 
} 

此映射0xRGBA - > 0xRRGGBBAA,或者可能0xHSVA - > 0xHHSSVVAA,但它不会做0xHSVA - > 0xRRGGBBAA。

+0

实际上,它将'0xRGBA'映射到'oxR0G0B0A0',这可能不是你想要的。 – 2011-12-20 17:57:08

+0

你必须以某种方式制作其他16位。 :) – zap 2011-12-20 17:58:47

+0

但是你可以用*好*信息而不是零来制作它们。 – 2011-12-20 18:00:39