gpt4 book ai didi

delphi - 添加 32 位 Bitmap 到 ImageList

转载 作者:行者123 更新时间:2023-12-03 15:00:55 26 4
gpt4 key购买 nike

我正在尝试在运行时创建并绘制 32 位位图,然后将其添加到 ImageList 中。位图具有透明度(alpha channel )。我可以毫无问题地创建位图并在其 Canvas 上进行绘制,并且它可以在任何其他 Canvas 上以透明度正常绘制。

问题是当我将其添加到 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');

如果我将此位图绘制到任何控件 Canvas 上,它会正常绘制,使用图像列表中的图像、圆角矩形和文本,具有透明背景(任何未绘制任何内容的地方都将是透明的;将保留原来的背景)已经在那了)。这意味着 Form1.Canvas.Draw(0, 0, Bitmap); 将在 Form1 上绘制位图,如果那里有任何其他图像,它将保留为背景。

但是,如果我将此位图添加到图像列表中,则会出现一个奇怪的问题。 ImageList 将其 ColorDepth 设置为 cd32bit,然后我调用:

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

现在,如果我尝试使用以下命令从图像列表中绘制该图像:

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

唯一会显示的是从 ImageList 中以 Bitmap 绘制的图像,圆角矩形和在 Canvas 中绘制的文本消失。

我错过了什么?

最佳答案

这可以通过创建一个额外的位图(Intrans)来完成,其 alpha channel 设置为 0。
Intrans用于ImageList。将原始位图添加为图像作为Mask。
该示例应该反射(reflect)您的示例。

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;

关于delphi - 添加 32 位 Bitmap 到 ImageList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19517704/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com