Search code examples
delphigditimagetbitmap

How to display a TBitmap with alpha channel on TImage correctly?


I have a TBitmap which contains semi-transparent image with alpha channel (in this example I got it from TPngImage).

var
  SourceBitmap: TBitmap;
  PngImage: TPngImage;
begin
  PngImage := TPngImage.Create();
  SourceBitmap := TBitmap.Create();
  try
    PngImage.LoadFromFile('ImgSmallTransparent.png');
    SourceBitmap.Assign(PngImage);
    SourceBitmap.SaveToFile('TestIn.bmp');
    imgSource.Picture.Assign(SourceBitmap);
  finally
    PngImage.Free();
    SourceBitmap.Free();
  end;

When I save this TBitmap to a TestIn.bmp file and open it with any image viewer, I can see the transparency. But when I assign it to TImage, transparent pixels appear as black (TImage has Transparent = True).

How to display TBitmap with transparency correctly on TImage?


Solution

  • Your shown code works fine on my system if I use Transparent=false for imgSource.
    I can reproduce the behavoiur with the black pixels if I load the bitmap from a file.

    Different setting influence the displaying enter image description here enter image description here enter image description here enter image description here

    procedure TForm3.SetAlphaFormatClick(Sender: TObject);
    begin
      if SetAlphaFormat.Checked then
        ToggleImage.Picture.Bitmap.alphaformat := afDefined
      else
        ToggleImage.Picture.Bitmap.alphaformat := afIgnored;
    end;
    
    procedure TForm3.SetImageTransparentClick(Sender: TObject);
    begin
      ToggleImage.Transparent := SetImageTransparent.Checked;
      Image1.Transparent := SetImageTransparent.Checked;
    end;
    
    procedure TForm3.LoadPngTransform2BitmapClick(Sender: TObject);
    Const
      C_ThePNG = 'C:\temp\test1.png';
      C_TheBitMap = 'C:\temp\TestIn.bmp';
    var
      SourceBitmap, TestBitmap: TBitmap;
      pngImage: TPngImage;
    begin
    
      Image1.Transparent := SetImageTransparent.Checked;
      pngImage := TPngImage.Create;
      SourceBitmap := TBitmap.Create;
      TestBitmap := TBitmap.Create;
      try
        pngImage.LoadFromFile(C_ThePNG);
        SourceBitmap.Assign(pngImage);
    
        {v1 with this version without the marked* part, I get the behavoir you described
          SourceBitmap.SaveToFile(C_TheBitMap);
          TestBitmap.LoadFromFile(C_TheBitMap);
          TestBitmap.PixelFormat := pf32Bit;
          TestBitmap.HandleType := bmDIB;
          TestBitmap.alphaformat := afDefined;  //*
          Image1.Picture.Assign(TestBitmap);
        }
        //> v2
        SourceBitmap.SaveToFile(C_TheBitMap);
        SourceBitmap.PixelFormat := pf32Bit;
        SourceBitmap.HandleType :=  bmDIB;
        SourceBitmap.alphaformat := afDefined;
        Image1.Picture.Assign(SourceBitmap);
        //< v2
      finally
        pngImage.Free;
        SourceBitmap.Free;
        TestBitmap.Free;
      end;
    end;