0

Qtを使用して次のことを行う場合:

  1. QImage::Format_RGB32 にビットマップをロードします。
  2. そのピクセルを RGB565 に変換します (これには Qt 形式がないため、「手動で」行う必要があります)。
  3. 手順 1 でロードしたものと同じサイズの新しいビットマップを作成します。
  4. 手順 3 で作成したイメージで、RGB565 バッファー ピクセルを RGB88 に戻します。
  5. 手順 4 で作成された画像は手順 1 の画像に似ていますが、RGB 値を比較するとまったく同じではありません。

手順 2 から 5 を繰り返すと、最終的な画像の色が失われ、ますます暗くなるように見えます。

ここに私の変換関数があります:

qRgb RGB565ToRGB888( unsigned short int aTextel )
{
    unsigned char r = (((aTextel)&0x01F) <<3);
    unsigned char g = (((aTextel)&0x03E0) >>2);
    unsigned char b = (((aTextel)&0x7C00 )>>7);
    return qRgb( r, g, b, 255 );
}

unsigned short int RGB888ToRGB565( QRgb aPixel )
{
    int red = ( aPixel >> 16) & 0xFF;
    int green = ( aPixel >> 8 ) & 0xFF;
    int blue =  aPixel & 0xFF;

    unsigned short  B = (blue >> 3) & 0x001F;
    unsigned short  G = ((green >> 2) < 5) & 0x07E0;
    unsigned short  R = ((red >> 3) < 11) & 0xF800;

    return (unsigned short int) (R | G | B);
}

私がテスト画像から見つけた適切に変換されない例は 4278192128 で、RGB565 から RGB888 に 4278190080 として変換されます。

編集: 元のソース データが RGB565 (テスト用の RGB888 イメージが作成された元) であることにも言及する必要があります。表示目的でのみ RGB888 に変換していますが、データの 2 つのコピーを保持するのではなく、後で RGB565 に変換したいと考えています。

4

1 に答える 1

9

前もって、2 つの変換関数のコンポーネントの順序が同じではないことを述べておきたいと思います。565→888変換では、赤成分は下位ビット( )を使うと想定していますが、赤成分0x001Fの5ビットをエンコードするときは上位ビット( )に入れます0xF8000xAARRGGBB(RGB565 でのバイナリ表現は) に類似したコンポーネントの順序が必要であると仮定すると、メソッド0bRRRRRGGGGGGBBBBB内の変数名を変更する必要がありますRGB565ToRGB888。以下のコードでこれを修正しました。

RGB565 から RGB888 への変換にバグがあります。緑のチャネルの場合、5 ビットを抽出すると、結果は 8 ビットではなく 7 ビットになります。青チャネルの場合、次のビットを取得しますが、これは結果的なエラーです。これで修正されるはずです:

QRgb RGB565ToRGB888( unsigned short int aTextel )
{
    // changed order of variable names
    unsigned char b = (((aTextel)&0x001F) << 3);
    unsigned char g = (((aTextel)&0x07E0) >> 3); // Fixed: shift >> 5 and << 2
    unsigned char r = (((aTextel)&0xF800) >> 8); // shift >> 11 and << 3
    return qRgb( r, g, b, 255 );
}

他の関数では、左シフト演算子の代わりに小なり演算子を誤って記述しました。これで修正されるはずです:

unsigned short int RGB888ToRGB565( QRgb aPixel )
{
    int red   = ( aPixel >> 16) & 0xFF;  // why not qRed(aPixel) etc. ?
    int green = ( aPixel >> 8 ) & 0xFF;
    int blue  =   aPixel        & 0xFF;

    unsigned short  B =  (blue  >> 3)        & 0x001F;
    unsigned short  G = ((green >> 2) <<  5) & 0x07E0; // not <
    unsigned short  R = ((red   >> 3) << 11) & 0xF800; // not <

    return (unsigned short int) (R | G | B);
}

コンポーネントからの色の構築と同様に、既存の (インライン) 関数qRedqGreenqBlueをコンポーネント抽出に使用できることに注意してください。qRgb

RGB888ToRGB565また、コンポーネント値は 8 ビットの範囲にあり、値を最初に右シフトしてから左シフトしてトリミングしたため、最後のビット マスクはオプションであることに注意してください。

于 2012-06-13T05:09:35.783 に答える