delphi - Agregar 32 bit Bitmap a ImageList
transparency (1)
Esto se puede hacer creando un mapa de bits adicional (Intrans) cuyo canal alfa se establece en 0.
Intrans se utiliza para ImageList.Add como imagen del mapa de bits original como Máscara.
El ejemplo debe reflejar el tuyo.
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;
Una versión más corta sería
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;
Estoy tratando de crear y pintar en tiempo de ejecución un mapa de bits de 32 bits, y luego agregarlo a una ImageList. El mapa de bits tiene transparencia (canal alfa). Puedo crear el mapa de bits y dibujar en su lienzo sin problemas, y se dibuja con transparencia con respecto a cualquier otro lienzo.
El problema es que cuando lo agrego a una ImageList, la imagen parece perder los dibujos realizados con la propiedad Canvas del mapa de bits.
Así es como comienzo el mapa de bits:
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'');
Si dibujo este mapa de bits a cualquier lienzo de control, dibuja normalmente, con la imagen de la lista de imágenes, el rectángulo redondeado y el texto, con fondo transparente (en cualquier lugar donde nada fue pintado será transparente; retendrá el fondo que ya estaba allí) . Significa que Form1.Canvas.Draw(0, 0, Bitmap);
dibujará el mapa de bits sobre el Form1 y si había alguna otra imagen allí, se mantendrá como fondo.
PERO, si agrego este mapa de bits a una lista de imágenes, se produce un problema extraño. La ImageList tiene su ColorDepth en cd32bit, y luego llamo a:
BitmapImageList.Width := Bitmap.Width;
BitmapImageList.Hieght := Bitmap.Height;
BitmapImageList.Add(Bitmap, nil);
Ahora, si trato de dibujar esa imagen desde la lista de imágenes con:
BitmapImageList.Draw(Form1.Canvas, 0, 0, 0);
Lo único que se mostrará es la imagen que se dibujó en Bitmap desde ImageList, el rect redondo y el texto que se dibujó en el Canvas desaparece.
¿Qué me estoy perdiendo?