【问题标题】:Adding 32 bits Bitmap to ImageList将 32 位位图添加到 ImageList
【发布时间】:2013-10-31 07:31:38
【问题描述】:

我正在尝试在运行时创建和绘制 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');

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

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

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

现在,如果我尝试从 imagelist 中绘制该图像:

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

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

我错过了什么?

【问题讨论】:

    标签: delphi bitmap transparency imagelist


    【解决方案1】:

    这可以通过创建一个附加位图 (Intrans) 来完成,其 alpha 通道设置为 0。
    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;
    

    【讨论】:

    • 干得好。我忘记了面具。我总是将图标添加到图像列表中,现在我记得当我制作图标时,必须指定一个蒙版。
    • 太棒了。我一直在寻找年龄问题的答案,但找不到任何答案。您的解决方案非常有效。最后要注意的是示例中的“BitmapImageList”必须将其 ColorDepth 设置为 cd24Bit。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多