8

TFTタッチスクリーンを使用したプロジェクトに取り組んでいます。この画面にはライブラリが含まれています。しかし、いくつか読んだ後、私はまだ何かを得ません。ライブラリには、色に関する定義がいくつかあります。

/* some RGB color definitions                                                 */
#define Black           0x0000      /*   0,   0,   0 */
#define Navy            0x000F      /*   0,   0, 128 */
#define DarkGreen       0x03E0      /*   0, 128,   0 */
#define DarkCyan        0x03EF      /*   0, 128, 128 */
#define Maroon          0x7800      /* 128,   0,   0 */
#define Purple          0x780F      /* 128,   0, 128 */
#define Olive           0x7BE0      /* 128, 128,   0 */
#define LightGrey       0xC618      /* 192, 192, 192 */
#define DarkGrey        0x7BEF      /* 128, 128, 128 */
#define Blue            0x001F      /*   0,   0, 255 */
#define Green           0x07E0      /*   0, 255,   0 */
#define Cyan            0x07FF      /*   0, 255, 255 */
#define Red             0xF800      /* 255,   0,   0 */
#define Magenta         0xF81F      /* 255,   0, 255 */
#define Yellow          0xFFE0      /* 255, 255,   0 */
#define White           0xFFFF      /* 255, 255, 255 */
#define Orange          0xFD20      /* 255, 165,   0 */
#define GreenYellow     0xAFE5      /* 173, 255,  47 */
#define Pink                        0xF81F

それらは16ビットカラーです。しかし、どのようにして 0, 128, 128 (ダーク シアン) から 0x03EF になるのでしょうか。つまり、16 ビット カラーを uint16 に変換する方法を教えてください。ライブラリにいくつかの色を追加したいだけなので、コードで答えを出す必要はありません。オンラインコンバーターへのリンク(私は見つけられませんでした)も大丈夫です:)

ありがとう

4

8 に答える 8

6

これらから、次の式を簡単に見つけることができます。

#define Red             0xF800      /* 255,   0,   0 */  
#define Magenta         0xF81F      /* 255,   0, 255 */
#define Yellow          0xFFE0      /* 255, 255,   0 */

F800 には 5 つの MSB ビットが設定されており、FFE0 には 5 つの LSB が設定されていません。0xF81F には明らかに 5 つの LSB と 5 つの MSB の両方が設定されており、フォーマットが RGB565 であることを証明しています。

値 173 を赤に変換する式は、見た目ほど単純ではありません。単純に最下位 3 ビットを削除することはできませんが、255 を 31 に対応させる (または緑の 255 を63)。

NewValue = (31 * old_value) / 255;

(そして、これはまだ切り捨てられた除算です。適切な丸めが必要になる可能性があります)。

適切な丸めとスケーリングを使用すると、次のようになります。

Uint16_value = (((31*(red+4))/255)<<11) | 
               (((63*(green+2))/255)<<5) | 
               ((31*(blue+4))/255);

編集JasonD によって有益に提案されたように括弧を追加しました。

于 2012-12-05T10:35:46.363 に答える
5

ディスプレイの正確なフォーマットを知る必要があります。「16ビット」だけでは不十分です。

RGB555があり、3つのコンポーネントのそれぞれが5ビットを取得します。これにより、合計色空間が32,768色に減少し、1ビットが無駄になりますが、各コンポーネントに同じ数の色合いがあるため、管理は非常に簡単です。

緑の成分が6ビットで与えられるRGB565もあります(人間の目は緑に対してより敏感であるため)。「ダークグリーン」の例は0x03e0バイナリでの例であるため、これは現在使用している形式である可能性があります0b0000 0011 1110 0000。そこには6ビットが1に設定されているので、これが緑色のコンポーネントの合計割り当てであり、最大値を示していると思います。

これは次のようになります(4ビットごとにスペースを区切り、架空の0bプレフィックスを再利用します)。

0bRRRR RGGG GGGB BBBB

もちろん、ビットの順序も異なる場合があります。

数値のトリプレットをビットパックされた単語に変換するタスクは、ビット操作演算子を備えた通常のプログラミング言語で非常に簡単に実行できます。

Cでは、多くの場合マクロで実行されますが、次の関数を使用することもできます。

#include <stdint.h>

uint16_t rgb565_from_triplet(uint8_t red, uint8_t green, uint8_t blue)
{
  red   >>= 3;
  green >>= 2;
  blue  >>= 3;
  return (red << 11) | (green << 5) | blue;
}

上記はコンポーネントの完全な8ビット精度を想定しているため、コンポーネントの最大強度は255であり、例のように128ではないことに注意してください。色空間が実際に7ビットコンポーネントを使用している場合は、追加のスケーリングが必要になります。

于 2012-12-05T10:27:05.410 に答える
4

RGB565 を使用しているようです。最初は赤に 5 ビット、次に緑に 6 ビット、次に青に 5 ビットです。

0xF800 でマスクし、右に 11 ビット シフトして赤のコンポーネントを取得する (または 8 ビットをシフトして 0 ~ 255 の値を取得する) 必要があります。0x07E0 でマスクし、右に 5 ビットシフトして緑のコンポーネントを取得します (または 3 ビットで 0 ~ 255 の値を取得します)。0x001F でマスクして青のコンポーネントを取得します (そして 3 ビット左にシフトして 0 ~ 255 を取得します)。

于 2012-12-05T10:35:40.840 に答える
3

色は 565 形式です。それらをバイナリで書き出すと、より明白になります。

  • 青、(0,0,255) は 0x001f で、00000 000000 11111 です
  • 緑、(0, 255, 0) は 0x07e0 で、00000 111111 00000
  • 赤 (255, 0, 0) は 0xf800 で、これは 11111 000000 00000 です

この形式で 24 ビット カラーを 16 ビットに変換するには、各コンポーネントから必要な上位ビットをマスクし、位置にシフトしてORまとめます。

16 ビットから 24 ビット カラーに変換し直し、各コンポーネントをマスクし、位置をシフトしてから、上位ビットを下位ビットに複製します。

あなたの例では、一部の色がシフトではなくスケーリングおよび丸められているようです。

31/255 のような係数でスケーリングするのではなく、ビット シフト方式を使用することを強くお勧めします。ビット シフトは高速になる可能性が高いだけでなく、より良い結果が得られるはずだからです。

于 2012-12-05T10:36:16.550 に答える
1

カラーチャネルごとにいくつのビットがあるかを知る必要があります。そうです、色には16ビットがありますが、RGBコンポーネントはそれぞれそれらのビットのサブセットです。あなたの場合、赤は5ビット、緑は6、青は5です。バイナリの形式は次のようになります。

RRRRRGGG GGGBBBBB

他にも16ビットのカラー形式があります。たとえば、赤、緑、青はそれぞれ5ビットで、残りのビットをアルファ値に使用します。

赤と青の両方のチャネルの値の範囲はから0まで2^5-1 = 31で、緑の値の範囲は0から2^6-1 = 63です。したがって、あなたの形で色から変換するには、(0->255),(0->255),(0->255)値を一方から他方にマップする必要があります。たとえば、範囲内の赤の値は128、範囲がの赤チャネルに0->255マップされます。切り捨てると、5ビットで表されるものが得られます。同様に、緑のチャネル(6ビット)の場合は、を取得します。したがって、色は16進数でマップされます。(128/255) * 31 = 15.60-311501111011111(128,128,128)01111011 111011110x7BEF

これを他の値に も0,128,128適用できます。00000011 111011110x03EF

于 2012-12-05T10:40:14.617 に答える
1

コードに表示される色はRGB565です。によって示されるように

#define Blue            0x001F      /*   0,   0, 255 */ 
#define Green           0x07E0      /*   0, 255,   0 */ 
#define Red             0xF800      /* 255,   0,   0 */

このリストに新しい色を追加したいだけの場合#defined、チャネルごとに16ビットUINTから変換する最も簡単な方法は、値を下にシフトして下位ビットを緩め、次にシフトして(または)16ビットRGBの位置に配置することです。価値。ただし、これによりバンディングアーティファクトが生成される可能性があり、より優れた変換方法がある可能性があります。

すなわち

UINT16 blue = 0xFF;
UINT16 green = 0xFF;
UINT16 red = 0xFF;


blue  >>= 11; // top 5 bits
green >>= 10; // top 6 bits
red   >>= 11; // top 5 bits

UINT16 RGBvalue = blue | (green <<5) | (red << 11)

これがどのように機能するかわからないため、シフト後に不要な漂遊ビットをマスクする必要があるかもしれませんが、上記のコードは機能するはずです。

于 2012-12-05T10:51:19.627 に答える
1

表示している 3 部構成の数値は、24 ビット カラーに適用できます。16 進数の 128 は 0x7f ですが、色の定義では 0x0f として表されています。同様に、255 は 0xff ですが、色の定義では 0x1f として表されています。これは、3 つの部分からなる数値を取得し、それらを 3 ビット下にシフトする必要があることを示唆しています (各色の色データの 3 ビットが失われます)。次に、それらを 1 つの 16 ビット数値に結合します。

uint16 color = ((red>>3)<<11) | ((green>>2)<<5) | (blue>>3);

...緑は 5 ビットではなく 6 ビットを使用するため、以前から修正されました。

于 2012-12-05T10:39:46.907 に答える