delphi bitmap transparency imagelist

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?