我正在尝试在运行时创建并绘制一个32位位图,然后将其添加到ImageList中。位图具有透明度(alpha通道)。我可以创建位图并在它的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');
如果我将此Bitmap绘制到任何控件画布,它会使用图像列表中的图像,圆角矩形和文本,使用透明背景(任何未绘制的任何内容都是透明的;将保留背景)进行正常绘制已经在那了)。这意味着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中绘制的文本消失。
我错过了什么?
答案 0 :(得分:5)
这可以通过创建其alpha字符串设置为0的附加位图(Intrans)来完成 Intrans用于ImageList.Add作为图像将原始位图作为Mask 这个例子应该反映你的。
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;