4

32 ビットの TBitmap を使用しているときに、Canvas.Pixels から ScanLine に切り替えました。

次に、値を赤に設定しましたが、青として表示されていました。

理由はありますか?

コードの抜粋を次に示します。

procedure TForm1.FormPaint(Sender: TObject);
var
  varBitmap: TBitmap;
  pLock: PIntegerArray;
  iColor: integer;
begin
  varBitmap := TBitmap.Create;
  varBitmap.PixelFormat := pf32bit;
  varBitmap.Width := 800;
  varBitmap.Height := 600;

  // Set Pixels to Red
  varBitmap.Canvas.Pixels[0, 0] := $0000FF;

  // Shows $FF0000 (blue)
  pLock := varBitmap.ScanLine[0];
  iColor := pLock[0];
  ShowMessageFmt('%x', [iColor]);

  // Set ScanLine to Red
  pLock[0] := $0000FF;

  // Displays a blue pixel
  Canvas.Draw(0, 0, varBitmap);
end;

どういうわけか TColor はメモリ内のものと同じではないようですが、それは意味がありません。

どんな提案でも大歓迎です。;)

4

2 に答える 2

6

VCL ビットマップ クラスTBitmapは、Windows ネイティブのデバイス非依存ビットマップ (DIB) のラッパーです。これらのビットマップ オブジェクトは、さまざまな異なるピクセル形式でビットマップを格納できます。それらは、1 ピクセルあたり 1 ビット、1 ピクセルあたり最大 32 ビット (使用している形式) のモノクロにすることができます。また、各ピクセルがカラー テーブルへのインデックスを保持するパレット ベースのビットマップを格納するためにも使用できます。

参照するピクセル データにアクセスする 2 つの方法は、 のPixelsプロパティTCanvasと のScanLineプロパティですTBitmap

PixelsプロパティはTCanvas、GDIGetPixelSetPixel関数のラッパーです。これらは、値を操作する高レベルの関数COLORREFです。のドキュメントにCOLORREFは次のように書かれています:

下位バイトには、赤の相対強度の値が含まれます。2 番目のバイトには緑の値が含まれます。3 番目のバイトには青の値が含まれます。上位バイトはゼロでなければなりません。1 バイトの最大値は 0xFF です。

つまり、COLORREF値には、ピクセルの色をエンコードする固定の方法があります。GetPixel関数と関数はSetPixel、固定COLORREF形式と基になる生のビットマップ ピクセル データとの間の変換を処理します。COLORREFaはアルファ値を表すことができないことにも注意してください。値はCOLORREF$00BBGGRR 形式です。

一方、 のScanLineプロパティはTBitmap、基になる DIB オブジェクトの生のピクセル データへのポインターを返します。ここで使用するデータは 32bpp ピクセル データであり、そのデータの規則では、$AARRGGBB 形式で保存されます。32bpp データの Windowsドキュメントには、次のように記載されています。

ビットマップには最大 2^32 色があります。BITMAPINFOHEADER の biCompression メンバーが BI_RGB の場合、BITMAPINFO の bmiColors メンバーは NULL です。ビットマップ配列の各 DWORD は、ピクセルの青、緑、および赤の相対的な強度を表します。青の値は最下位 8 ビットで、その後に緑と赤のそれぞれ 8 ビットが続きます。各 DWORD の上位バイトは使用されません。

実際、このテキストは正しくなく、時代遅れです。それぞれの上位バイトDWORDは、使用されている場合、実際にはアルファ チャネルです。

于 2014-03-10T13:24:45.547 に答える