我有一個16位的位圖圖像,每一種顏色代表一個短的(2字節),我需要在32位位圖上下文中顯示。如何在C++中將2字節的顏色轉換爲4字節的顏色?轉換16bit顏色爲32bit
輸入格式在單個短(2字節)中包含每種顏色。
輸出格式是32位RGB。這意味着每個像素都有3個字節,我相信?
我需要將短的值轉換成RGB顏色。
請原諒我對顏色的認識不足,這是我第一次進入圖形編程領域。
我有一個16位的位圖圖像,每一種顏色代表一個短的(2字節),我需要在32位位圖上下文中顯示。如何在C++中將2字節的顏色轉換爲4字節的顏色?轉換16bit顏色爲32bit
輸入格式在單個短(2字節)中包含每種顏色。
輸出格式是32位RGB。這意味着每個像素都有3個字節,我相信?
我需要將短的值轉換成RGB顏色。
請原諒我對顏色的認識不足,這是我第一次進入圖形編程領域。
常用格式包括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);
*/
}
乘以三(四,當你有一個alpha層)的16個值 - 這是它:)
你有一個16位彩色,並希望使其成爲32位色。這給你四位四位,你想要轉換成四位八位。您要添加四位數,但您應該將它們添加到值的右側。爲此,將它們移位四位(乘以16)。此外,您可以通過添加8(您添加4位,其值爲0-15,並且您可以取8的平均值進行補償)補償一點不準確性。
更新這隻適用於每個通道使用4位的顏色並具有Alpha通道。
此解決方案有點幼稚 - 它會留下黑色黑色,但白色會變成灰色。 – 2011-12-20 17:39:04
@CarlNorum正如我所說,你總是在編造數據。沒有完美的解決方案。 – 2011-12-20 17:41:31
你總是可以嘗試彌補*好*的信息。在這種情況下,事實上,有一個保證最小的錯誤解決方案 - 請參閱我的答案。 – 2011-12-20 17:47:04
通常,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%
還有一些關於模型的問題就像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。
實際上,它將'0xRGBA'映射到'oxR0G0B0A0',這可能不是你想要的。 – 2011-12-20 17:57:08
你必須以某種方式製作其他16位。 :) – zap 2011-12-20 17:58:47
但是你可以用*好*信息而不是零來製作它們。 – 2011-12-20 18:00:39
你在iOS上用C++做什麼?只需使用UIImage或cocos2d。 – 2011-12-20 17:22:49
您提到了三種不同的源格式:每像素16位,每種顏色2個字節,以及「單字節顏色」。這是什麼? – interjay 2011-12-20 17:26:27
取決於按位格式... 565/555/556/655等 – tenfour 2011-12-20 17:30:18