Search code examples
delphipngalpha-transparencytbitmap

Remove BMP background and convert to trasparent PNG with Delphi


I have a TBitmap, inside the TBitmap there is load a "map image" (image of a map). This map image have a white background and a lot of black line (no antialising only 2 colors white background and black line).

Now I must do this:

  • Remove the white background from TBitmap (transparent background and black line);
  • If possible and only if possible replace black line color with another color;
  • Save the result as trasparent PNG image;

I don't have idea if these are possible. Suggestions?

NOTE I want avoid to use 3th part of class or VCL if possible. I can use FreeImage library if need because I just use it on my project. I use Delphi XE3.


Solution

  • Change pixelformat to pf1Bit. Create a palette with 2 entries, change the values of the TPaletteEntry to the desired color value (in the shown exaple to red). Create a TPNGImage, assign the bitmap and set the transparency for the PNG.

    implementation
    uses pngimage;
    {$R *.dfm}
    
    Type
      TMyPalette = Packed Record
         palVersion : Word;
         palNumEntries : Word;
         palPalEntry : Array [0..1] of TPaletteEntry;
       End;
    
    Procedure ChangeBlackColor(bmp:TBitMap);
    var
     pal:TMyPalette;
    begin
       bmp.PixelFormat := pf1Bit;
       bmp.HandleType  := bmDIB;
        With pal Do
        Begin
          palVersion:=$0300;
          palNumEntries:=2;
          palPalEntry[0].peRed:= $FF;
          palPalEntry[0].peGreen:=$00;
          palPalEntry[0].peBlue:= $00;
          palPalEntry[0].peFlags:=PC_RESERVED;
          palPalEntry[1].peRed:= $FF;
          palPalEntry[1].peGreen:=$FF;
          palPalEntry[1].peBlue:= $FF;
          palPalEntry[1].peFlags:=PC_RESERVED;
        End;
       bmp.Palette := CreatePalette(pLogPalette(@pal)^)
    end;
    
    
    
    procedure TForm3.Button1Click(Sender: TObject);
    var
     png:TPngimage;
     bmp:TBitmap;
    begin
      // sample image
      Image1.Canvas.Rectangle(0,0,Image1.Width-1,Image1.Height-1);
      Image1.Canvas.Ellipse(1,1,Image1.Width,Image1.Height);
    
    
    
      bmp := Image1.Picture.Bitmap;
    
      ChangeBlackColor(bmp);
    
      png:=TPngimage.Create;
      try
         png.Assign(bmp);
         png.TransparentColor := clWhite;
         png.Transparent := true;
         Image2.Picture.Assign(png);
      finally
        png.Free;
      end;
    end;
    

    enter image description here