Search code examples
imagedelphipngsavetransparency

How to save a png file with transparency?


I am using Barcode Studio 2011 to paint a QR Code into a Graphics32 - TImage32 Component and I want to save it in png format but with the white colour as transparent this I have specified in the OuterColor of Graphics32.

OnFormCreate I have just

procedure TForm1.FormCreate(Sender: TObject);
begin
  psBarcodeComponent1.BarCode := 'some text here...';
end;

and for the moment I have the painting assigned to a Button Click Event

procedure TForm1.Button8Click(Sender: TObject); // Paint the barcode
var
  bmp: TBitmap32;
  Coords: TRect;
begin
 bmp := TBitmap32.Create;
 bmp.SetSize(image.Width, image.Height);
 bmp.Canvas.Brush.Color := color;
 bmp.Canvas.Rectangle(-1, -1, image.Width+2, image.Height+2);

 bmp.DrawMode := dmTransparent;
 bmp.OuterColor := clWhite;

 // make Coords the size of image
 Coords := Rect(0,0,image.Width,image.Height);
 psBarcodeComponent1.PaintBarCode(bmp.Canvas, Coords);
 image.Bitmap.Assign(bmp);
end;

I am using the Vampyre Imaging Library to convert the Bitmap into PNG Format but I will gladly use any library, function, and advice - I have been trying to do this now for nearly a week! I have read through and re-read the documentation of graphics32 and also of the Vampyre Imaging Library but nothing I try will convert the white to a transparent colour. I have tried clWhite, clWhite32 and also setting the drawMode to dmBlend and applying the ChromaKey Function all to no avail but plenty frustration, coffee and a little beer also ;)

This is how I am saving it...

procedure TForm1.Button7Click(Sender: TObject); // Save with Vampyre Imaging Lib
{ Try to save in PNG format with transparancy }
var
  FImage: TSingleImage;
begin
  FImage := TSingleImage.Create;
  ConvertBitmap32ToImage(image.Bitmap, FImage);
  FImage.SaveToFile('VampyreLibIMG.png');
end;  

This results in a Black coloured thumbnail and when viewed in Windows Photo Viewer it is completely transparent.

I hope that I have provided enough information and that someone is able to help me.

Chris


Solution

  • This approach works for me:

    uses GR32, GR32_PNG, GR32_PortableNetworkGraphic;
    
    var
      Y: Integer;
      X: Integer;
      Png: TPortableNetworkGraphic32;
    
      function IsWhite(Color32: TColor32): Boolean;
      begin
        Result:= (TColor32Entry(Color32).B = 255) and
                 (TColor32Entry(Color32).G = 255) and
                 (TColor32Entry(Color32).R = 255);
      end;
    
    begin
      with Image321 do
      begin
        Bitmap.ResetAlpha;
        for Y := 0 to Bitmap.Height-1 do
          for X := 0 to Bitmap.Width-1 do
          begin
            if IsWhite(Bitmap.Pixel[X, Y]) then
              Bitmap.Pixel[X,Y]:=Color32(255,255,255,0);
          end;
        Png:= TPortableNetworkGraphic32.Create;
        Png.Assign(Bitmap);
        Png.SaveToFile('C:\Temp\NowTransparent.png');
        Png.Free;
      end;
    end;
    

    This uses the GR32 PNG library. It's a pretty direct way, setting all white pixels to transparent.

    PS: Image321 is a TImage32 component, containing my TBitmap32.