2013-10-22 6 views
5

私は実行時に32ビットのビットマップを作成しペイントしてImageListに追加しようとしています。ビットマップには透明度(アルファチャンネル)があります。ビットマップを作成してキャンバスに問題なく描画することができ、他のキャンバスに比べて透過的に描画されます。ImageListに32ビットのビットマップを追加する

問題は、ImageListに追加すると、画像がビットマップのCanvasプロパティで作成された図面を失うように見えることです。ここで

は、私はビットマップを起動する方法です:

Bitmap := TBitmap.Create; 
Bitmap.PixelFormat := pf32bit; 
Bitmap.Transparent := True; 
Bitmap.AlphaFormat := afDefined; 
SetBkMode(Bitmap.Canvas.Handle, TRANSPARENT); 
Bitmap.SetSize(100, 42); 

// now I can draw, let's say, an icon from an imagelist 
ImageList.Draw(Bitmap.Canvas, 5, 5, 0, dsTransparent, itImage); 

// and some other stuff 
Bitmap.Canvas.RoundRect(0, 0, 99, 41, 5, 5); 
Bitmap.Canvas.TextOut(50, 5, 'Test string'); 

私は任意のコントロールのキャンバスに、このビットマップを描画した場合、それは透明な背景を持つ、イメージリストからイメージ、角の丸い四角形とテキストで、normaly描きます(何も塗られていない場所は透明になり、既にそこにあった背景は保持されます)。これは、Form1.Canvas.Draw(0, 0, Bitmap);がForm1を介してビットマップを描画し、そこに他のイメージがあれば、それがバックグラウンドとして保持されることを意味します。

しかし、このビットマップをイメージリストに追加すると、奇妙な問題が発生します。今

BitmapImageList.Width := Bitmap.Width; 
BitmapImageList.Hieght := Bitmap.Height; 
BitmapImageList.Add(Bitmap, nil); 

、私はイメージリストからそのイメージを描画しようとした場合::

BitmapImageList.Draw(Form1.Canvas, 0, 0, 0); 

表示される唯一のものがあるイメージリストは、それがカラー深度がcd32bitに設定されます、そして、私は呼んありImageListからビットマップで描画されたイメージ、丸められた矩形、およびキャンバスに描画されたテキストは消えます。

私には何が欠けていますか?

答えて

5

これは、アルファチャンネルが0に設定されている追加のビットマップ(Intrans)を作成することで行うことができます。
IntransがImageListに使用されます。イメージとしてマスクとして元のビットマップを追加します。
この例には自分自身が反映されているはずです。

type 
    pRGBQuadArray = ^TRGBQuadArray; 
    TRGBQuadArray = ARRAY [0 .. 0] OF TRGBQuad; 

Procedure GenIntransparentBitmap(bmp, Intrans: TBitmap); 
var 
    pscanLine32: pRGBQuadArray; 
    i, j: Integer; 
begin 
    Intrans.Assign(bmp); 
    for i := 0 to Intrans.Height - 1 do 
    begin 
    pscanLine32 := Intrans.Scanline[i]; 
    for j := 0 to Intrans.Width - 1 do 
    begin 
     pscanLine32[j].rgbReserved := 0; 
    end; 
    end; 
end; 

procedure TForm3.Button1Click(Sender: TObject); 
var 
    Bitmap, Intransp: TBitmap; 
begin 
    Bitmap := TBitmap.Create; 
    try 
    Bitmap.PixelFormat := pf32bit; 
    Bitmap.Transparent := true; 
    Bitmap.AlphaFormat := afIgnored; 
    SetBkMode(Bitmap.Canvas.Handle, BKMODE_LAST); 
    Bitmap.SetSize(100, 42); 

    ImageList1.Draw(Bitmap.Canvas, 5, 5, 0, dsTransparent, itImage); 

    Bitmap.Canvas.Brush.Style := bsClear; 
    Bitmap.Canvas.RoundRect(0, 0, 99, 41, 5, 5); 
    Bitmap.Canvas.TextOut(50, 5, 'Test string'); 

    BitmapImageList.Width := Bitmap.Width; 
    BitmapImageList.Height := Bitmap.Height; 

    // Create intransparent bitmap from transparent bitmap 
    Intransp := TBitmap.Create; 
    try 
     GenIntransparentBitmap(Bitmap, Intransp); 
     // add intransparent bitmap as image and transparent bitmap as mask 
     BitmapImageList.Add(Intransp, Bitmap); 
    finally 
     Intransp.Free; 
    end; 

    BitmapImageList.Draw(Canvas, 100, 100, 0); 
    finally 
    Bitmap.Free; 
    end; 
end; 

短いバージョンはよくやっ

Procedure GenIntransparentBitmap(bmp, Intrans: TBitmap); 
begin 
    Intrans.Assign(bmp); 
    Intrans.PixelFormat := pf24bit; 
end; 

procedure TForm3.Button1Click(Sender: TObject); 
var 
    Bitmap, Intransp: TBitmap; 
begin 
    Bitmap := TBitmap.Create; 
    try 
    Bitmap.PixelFormat := pf32bit; 

    SetBkMode(Bitmap.Canvas.Handle, TRANSPARENT); 
    Bitmap.SetSize(100, 42); 

    ImageList1.Draw(Bitmap.Canvas, 5, 5, 0, dsTransparent, itImage); 

    Bitmap.Canvas.Brush.Style := bsClear; 
    Bitmap.Canvas.RoundRect(0, 0, 99, 41, 5, 5); 
    Bitmap.Canvas.TextOut(50, 5, 'Test string'); 

    BitmapImageList.Width := Bitmap.Width; 
    BitmapImageList.Height := Bitmap.Height; 

    // Create intransparent bitmap from transparent bitmap 
    Intransp := TBitmap.Create; 
    try 
     GenIntransparentBitmap(Bitmap, Intransp); 
     // add intransparent bitmap as image and transparent bitmap as mask 
     BitmapImageList.Add(Intransp, Bitmap); 
    finally 
     Intransp.Free; 
    end; 

    BitmapImageList.Draw(Canvas, 100, 100, 0); 
    finally 
    Bitmap.Free; 
    end; 
end; 
+1

だろう。私はマスクについて忘れてしまった。私はいつも画像リストにアイコンを追加しています。アイコンを作成するときは、マスクを指定することが不可欠です。 –

+0

私はその問題の形の年齢に対する答えを探していて、何も見つけることができませんでした。あなたのソリューションは完璧に機能します。最後の注意点は、この例の「BitmapImageList」は、ColorDepthをcd24Bitに設定する必要があることです。どうもありがとうございました。 – Marcio

関連する問題