どのような変換の16ビットRGB565 24ビットRGB888?
質問
私には自分の手に16ビットrgb565画(具体的には、Android framebufferダンプ)に、どのような変換する24ビットrgb888でご利用いただくための通常のモニタです。
それでは、どのような変換5または6ビットのチャンネルを8ビット?その答えをシフトします。いでこれを書き:
puts("P6 320 480 255");
uint16_t buf;
while (read(0, &buf, sizeof buf)) {
unsigned char red = (buf & 0xf800) >> 11;
unsigned char green = (buf & 0x07e0) >> 5;
unsigned char blue = buf & 0x001f;
putchar(red << 3);
putchar(green << 2);
putchar(blue << 3);
}
しかし、これは当てはまりませんって一件れていきたいと考えているのは 0xffff
地図へ 0xffffff
, ではなく、 0xf8fcf8
.私の価値の一部は、なんなのかかるすべきます。
Android SDK付属というツールddms(オブダールヴィークのデバッグモニターするスクリーンキャプチャー画面.調査を実施しているのは、同じか の読み込みコード, で実施し、同じ論理学その画面ようとする試みが出てきた相異なり、白をマッピングを白にしています。
こちらの 原framebuffer, は、 スマートに変換 によるddms、 ダム変換 上記のアルゴリズムです。なお、後者はやや濃緑.
(ちなみに、この変換 が実施されgparted, ですが、すぐにダムの変換には、上記のLSBsで全てゼロになります。)
思うまくいきませんの質問:
- 何が最も感度の良い方法で変換しrgb565にrgb888?
- どのようにDDMSを変換し、その画面表示?
解決
あなたはシフトした後、または最上位ビットを持つことができ、すなわちます。
Red 10101 becomes 10101000 | 101 => 10101101
12345 12345--- 123 12345123
これは、あなたが求める性質を持っていますが、それは、他の1つの空間からの値の最も線形マッピングではありません。これは、しかし、高速です。 :)
Cletus'答えは、より完全な、おそらくより良いです。 :)
他のヒント
したい地図をそれぞれからは5/6ビットスペースを8ビットのスペース。
- 5ビット=32値
- 6ビット=64値
- 8ビット=256値
このコードを使うには、ナイーブアプローチx5*256/32=x8が256/32=8を乗じて8左シフト3ですが、あなたの言葉を借りれ、これは当てはまりません必ず記入し、新しい番号をスペース"正しく".5-8最大値は31日255るお問のソリューションとなります。
x8 = 255/31 * x5
x8 = 255/63 * x6
場所 x5
, x6
や x8
5、6、8ビットの値です。
現在はそれだけではありませんかつ最良の方法を実施します。なる部門は、整数部門にまわったモニタリングルームも残り、結果(少が基本で、最善の解決策であろう浮動小数点演算によって半分にまでなったのは整数です。
この高速化を大幅にを使っているだけではこの式を生成するルックアップテーブルのそれぞれ5と6のビット変換式
私の数セントます:
あなたが正確なマッピングを気にしている場合、まだ高速アルゴリズムは、あなたがこれを考慮することができます:
R8 = ( R5 * 527 + 23 ) >> 6;
G8 = ( G6 * 259 + 33 ) >> 6;
B8 = ( B5 * 527 + 23 ) >> 6;
それはかなり速いですので、> - MUL、ADDとSHR:これはのみを使用しています! 他の側面から、それが適切な丸め付き浮動小数点へのマッピング100%互換性があります:
// R8 = (int) floor( R5 * 255.0 / 31.0 + 0.5);
// G8 = (int) floor( G6 * 255.0 / 63.0 + 0.5);
// B8 = (int) floor( R5 * 255.0 / 31.0 + 0.5);
いくつかの余分なセント: あなたは888 565への変換に興味があるなら、これはあまりにも非常によく動作します:
R5 = ( R8 * 249 + 1014 ) >> 11;
G6 = ( G8 * 253 + 505 ) >> 10;
B5 = ( B8 * 249 + 1014 ) >> 11;
定数は少しの事をスピードアップするためにいくつかの初期の拒絶で力まかせ探索を使用していた。
iOS vImage変換
の iOSの枠組みを加速 書類は次のアルゴリズムの vImageConvert_RGB565toARGB8888
機能:
Pixel8 alpha = alpha
Pixel8 red = (5bitRedChannel * 255 + 15) / 31
Pixel8 green = (6bitGreenChannel * 255 + 31) / 63
Pixel8 blue = (5bitBlueChannel * 255 + 15) / 31
のための一時的な変換をこの分が処理を行いたい場合多くのフレームを利用したいようなものiOS vImage変換の実行を自分で用 ネオンintrinsics.
腕から地域フォーラムのチュートリアル
第一に、見ていただきますの変換RGB565にRGB888.いが16ビットピクセルの登録q0,めてまいりたいと思いま別の赤、緑、青に8ビット素子を越え、レジスタd2d4.
vshr.u8 q1, q0, #3 @ shift red elements right by three bits,
@ discarding the green bits at the bottom of
@ the red 8-bit elements.
vshrn.i16 d2, q1, #5 @ shift red elements right and narrow,
@ discarding the blue and green bits.
vshrn.i16 d3, q0, #5 @ shift green elements right and narrow,
@ discarding the blue bits and some red bits
@ due to narrowing.
vshl.i8 d3, d3, #2 @ shift green elements left, discarding the
@ remaining red bits, and placing green bits
@ in the correct place.
vshl.i16 q0, q0, #3 @ shift blue elements left to most-significant
@ bits of 8-bit color channel.
vmovn.i16 d4, q0 @ remove remaining red and green bits by
@ narrowing to 8 bits.
の効果の指示に記載のコメントは、概要、この操作を行い、各チャンネルは削除色データを隣接するチャンネル用シフトのビットオフのいずれかの要素になります。利用目へのシフト位置のカラーデータの最大ビットの各要素に、狭削減の要素サイズを16から最上位ビット.
注意の要素サイズをこのシーケンスに対8の16ビット素子の実現のために、一部のマスキング事業です。
小さな問題
また、ご利用の場合は上記コードへの変換にRGB888形式でも、白いも白になります。これは、各チャンネル最小二、三のビットはゼロではなく一;白色に表されるRGB565として(0x1F,0x3F,0x1F)が(0xF8,0xFC,0xF8)RGB888.この固定できる利用への挿入する場所の最大ビットのビット.
のためのアンドロイドの特定の例を発見 YUVにRGB変換 書intrinsics.
これを試してください:
red5 = (buf & 0xF800) >> 11;
red8 = (red5 << 3) | (red5 >> 2);
これは、すべて1年代に、すべてゼロにすべて1をすべてゼロをマップする、との間のすべてに間にすべてします。あなたがワンステップで所定の場所にビットをシフトすることによって、それがより効率的にすることができます:
redmask = (buf & 0xF800);
rgb888 = (redmask << 8) | ((redmask<<3)&0x070000) | /* green, blue */
は、同様に、緑および青(6ビット分、シフト上部方法でそれぞれ2及び右4左)ください。
一般的な解決策は、バイナリ分数として番号を処理することである - したがって、6ビット番号63/63は、8ビット数255/255と同じです。あなたは他のポスターがお勧めのように、ルックアップテーブルを計算し、最初にこの使用して浮動小数点演算を計算することができます。また、これは、ビットバッシングのソリューションに比べ、より直感的であるという利点があります。 :)
エラーjleedevがあります!!!
unsigned char green = (buf & 0x07c0) >> 5;
unsigned char blue = buf & 0x003f;
良いコード
unsigned char green = (buf & 0x07e0) >> 5;
unsigned char blue = buf & 0x001f;
乾杯、 アンディ
私は次のように使用して良い結果を得ました。 。私のLogitekカムがRGB555 16ビットおよびRGB888は私がIJG小動物を使用して、JPEGとして保存することができ24ビットに変換するために、次を使用していたが判明:StackOverflowの上ここで見つけるヒントをお寄せいただきありがとうございます。
// Convert a 16 bit inbuf array to a 24 bit outbuf array
BOOL JpegFile::ByteConvert(BYTE* inbuf, BYTE* outbuf, UINT width, UINT height)
{ UINT row_cnt, pix_cnt;
ULONG off1 = 0, off2 = 0;
BYTE tbi1, tbi2, R5, G5, B5, R8, G8, B8;
if (inbuf==NULL)
return FALSE;
for (row_cnt = 0; row_cnt <= height; row_cnt++)
{ off1 = row_cnt * width * 2;
off2 = row_cnt * width * 3;
for(pix_cnt=0; pix_cnt < width; pix_cnt++)
{ tbi1 = inbuf[off1 + (pix_cnt * 2)];
tbi2 = inbuf[off1 + (pix_cnt * 2) + 1];
B5 = tbi1 & 0x1F;
G5 = (((tbi1 & 0xE0) >> 5) | ((tbi2 & 0x03) << 3)) & 0x1F;
R5 = (tbi2 >> 2) & 0x1F;
R8 = ( R5 * 527 + 23 ) >> 6;
G8 = ( G5 * 527 + 23 ) >> 6;
B8 = ( B5 * 527 + 23 ) >> 6;
outbuf[off2 + (pix_cnt * 3)] = R8;
outbuf[off2 + (pix_cnt * 3) + 1] = G8;
outbuf[off2 + (pix_cnt * 3) + 2] = B8;
}
}
return TRUE;
}