Article

From:
To:
gerd platl
Subject:
Re: Transparent PNG (Graphics32 1.9)
Newsgroup:
graphics32.general

Re: Transparent PNG (Graphics32 1.9)

> this works fine for me...
> http://graphics32.org/news/newsgroups.php?art_group=graphics32.general&article_id=6918

Ooh sorry - this version has a bug and edit lines are brocken!

Attached you'll find the corrected version and a transparent PNG example ... ;-)


//******************************************************************* // // UNIT: G r 3 2 _ P N G 15.Jan.2005, 19. March 2010 // // PNG Graphic Unit for graphics32 library v1.7.x and higher // to load and save PNG images (Portable Network Graphics) // Tested with graphics32 v1.9.0 2010-03-08 // // needs TPNGImage component from Gustavo Daud (✉uol.com.br) // http://pngdelphi.sourceforge.net/ // // Tested with: graphics32 v1.9.0 2010-03-08 // PNGImage v1.564 2006-07-25. // // FAQ: // Q: Is there a PNG library for GR32 which supports loading and saving // an image and its alpha channel at the same time? // // A: Yes, you need TPNGImage component from Gustavo Daud // and this unit to load and save PNG images. // // LoadPNGintoBitmap32 code taken from // http://graphics32.org/wiki/pub/page/FAQ/ImageFormatRelated // // note: if you use standard picture file dialogs of type TOpenPictureDialog // or TSavePictureDialog to load or save PNG pictures, you have to add // string "Portable Network Graphics (*.png)" and "*.png" // to filter property ! // // --- functions and procedures --- // // LoadPNGintoBitmap32 load PNG image file into Bitmap32 // SaveBitmap32ToPNG save Bitmap32 to PNG image file // // Bitmap32ToPNG convert Bitmap32 to PNG object // //******************************************************************* {$I comp_opt.inc}
unit Gr32_PNG;
INTERFACE
uses SysUtils, Classes, Graphics, GR32, PNGImage;
function LoadPNGintoBitmap32 (destBitmap: TBitmap32;                               srcStream: TStream;                               out transparent: Boolean): boolean; overload;
function LoadPNGintoBitmap32 (destBitmap: TBitmap32;                               filename: String;                               out transparent: Boolean): boolean; overload;
function SaveBitmap32ToPNG (sourceBitmap: TBitmap32;                             transparent: Boolean;                             bgColor32: TColor32;                             filename: String;                             compressionLevel: TCompressionLevel = 9;
interlaceMethod: TInterlaceMethod = imNone): boolean;

function Bitmap32ToPNG (sourceBitmap: TBitmap32;
                        paletted, transparent: Boolean;
                        bgColor: TColor;
                        compressionLevel: TCompressionLevel = 9;
                        interlaceMethod: TInterlaceMethod = imNone): tPNGObject;

IMPLEMENTATION
//********************************************************* // load PNG image from source stream // input: destBitmap: TBitmap32; destination bitmap // srcStream: TStream; source stream // output: transparent: boolean; =true: alpha channel used // return: boolean; =true: png image file loaded // destBitmap: TBitmap32; destination bitmap data //--------------------------------------------------------- function LoadPNGintoBitmap32 (destBitmap: TBitmap32;                               srcStream: TStream;                               out transparent: Boolean): boolean; var   PNGObject: TPNGObject;   TransparentColor: TColor32;   PixelPtr: PColor32;   AlphaPtr: PByte;   X, Y: Integer; begin   PNGObject := nil;   try     result := false;     // if two images with same size are loaded and 2nd has transparent pixel     // the color value are not cleared -> this is a BUG     destBitmap.Clear($FF000000); // bug correction!     PNGObject := TPngObject.Create;     PNGObject.LoadFromStream(srcStream);
    destBitmap.Assign(PNGObject); // destBitmap.ResetAlpha; // bug correction!
    case PNGObject.TransparencyMode of       ptmPartial:         begin           if (PNGObject.Header.ColorType = COLOR_GRAYSCALEALPHA) or              (PNGObject.Header.ColorType = COLOR_RGBALPHA) then           begin             PixelPtr := PColor32(@destBitmap.Bits[0]);             for Y := 0 to destBitmap.Height - 1 do             begin               AlphaPtr := PByte(PNGObject.AlphaScanline[Y]);               for X := 0 to destBitmap.Width - 1 do               begin
PixelPtr^ := (PixelPtr^ and $00FFFFFF) or (TColor32(AlphaPtr^) shl 24);
                Inc(PixelPtr);                 Inc(AlphaPtr);               end;
            end;
            transparent := True;
          end;
        end;
      ptmBit:
        begin
          TransparentColor := Color32(PNGObject.TransparentColor);
          PixelPtr := PColor32(@destBitmap.Bits[0]);
          for X := 0 to (destBitmap.Height - 1) * (destBitmap.Width - 1) do
          begin
            if PixelPtr^ = TransparentColor then
              PixelPtr^ := PixelPtr^ and $00FFFFFF;
            Inc(PixelPtr);
          end;
          transparent := True;
        end;
      ptmNone:
        transparent := False;
    end;
    result := true;
  finally
    if Assigned(PNGObject) then PNGObject.Free;
  end;
end;
//*********************************************************
// load PNG image file into Bitmap32
// input:   destBitmap: TBitmap32;    destination bitmap
//          filename: String;         name of PNG image file
// output:  transparent: boolean;     =true: alpha channel used
// return:  boolean;                  =true: png image file loaded
//---------------------------------------------------------
function LoadPNGintoBitmap32 (destBitmap: TBitmap32;
                              filename: String;
                              out transparent: boolean): boolean;
var
  FileStream: TFileStream;
begin
  result := false;
  try
    FileStream := TFileStream.Create(filename, fmOpenRead);
    try
      result := LoadPNGintoBitmap32(destBitmap, FileStream, transparent);
    finally
      FileStream.Free;
    end;
  except
  end;
end;

//********************************************************* // convert Bitmap32 to PNG image // input: sourceBitmap source bitmap 32 bit // paletted =true: PixelFormat is pf8bit // transparent =true: transparent pixels // bgColor background color // compressionLevel compression level, range 0..9, default = 9 // interlaceMethod interlaced method, use imNone or imAdam7 // return: tPNGObject PNG image object //--------------------------------------------------------- function Bitmap32ToPNG (sourceBitmap: TBitmap32;                         paletted, transparent: Boolean;                         bgColor: TColor;                         compressionLevel: TCompressionLevel = 9;                         interlaceMethod: TInterlaceMethod = imNone): tPNGObject; var   bm: TBitmap;   png: TPngObject;   TRNS: TCHUNKtRNS;   p: pngImage.PByteArray;   x, y: Integer; begin   Result := nil;   png := TPngObject.Create;   try     bm := TBitmap.Create;     try       bm.Assign (sourceBitmap); // convert data into bitmap       // force paletted on TBitmap, transparent for the web must be 8bit       if paletted then         bm.PixelFormat := pf8bit;       png.interlaceMethod := interlaceMethod;       png.compressionLevel := compressionLevel;       png.Assign(bm); // convert bitmap into PNG     finally       FreeAndNil(bm);     end;     if transparent then begin       if png.Header.ColorType in [COLOR_PALETTE] then begin         if (png.Chunks.ItemFromClass(TChunktRNS) = nil) then png.CreateAlpha;         TRNS := png.Chunks.ItemFromClass(TChunktRNS) as TChunktRNS;         if Assigned(TRNS) then TRNS.TransparentColor := bgColor;       end;
if png.Header.ColorType in [COLOR_RGB, COLOR_GRAYSCALE] then png.CreateAlpha;
      if png.Header.ColorType in [COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA] then
      begin
        for y := 0 to png.Header.Height - 1 do begin
          p := png.AlphaScanline[y];
          for x := 0 to png.Header.Width - 1
do p[x] := AlphaComponent(sourceBitmap.Pixel[x,y]); // TARGB(bm.Pixel[x,y]).a;
        end;
      end;
    end;
    Result := png;
  except
    png.Free;
  end;
end;

//********************************************************* // save Bitmap32 to PNG image file // input: srcBitmap source bitmap // transparent =true: transparent pixels // bgColor32 background color 32 bit // compressionLevel compression level, range 0..9, default = 9 // interlaceMethod interlaced method, use imNone or imAdam7 // return: boolean =true: bitmap saved as PNG image file //--------------------------------------------------------- function SaveBitmap32ToPNG (sourceBitmap: TBitmap32;                             transparent: Boolean;                             bgColor32: TColor32;                             filename: String;                             compressionLevel: TCompressionLevel = 9;
interlaceMethod: TInterlaceMethod = imNone): boolean;
var  png: tPNGObject;
begin
  result := false;
  try
    png := Bitmap32ToPNG (sourceBitmap, false, transparent, WinColor(bgColor32),
                          compressionLevel, interlaceMethod);
    try
      png.SaveToFile (filename);
      result := true;
    finally
      png.Free;
    end;
  except
  end;
end;
//---------------------------------------------------------
// file stream variant to save bitmap32 as PNG picture file
//---------------------------------------------------------
(*
function xSaveBitmap32ToPNG (sourceBitmap: TBitmap32;
                            transparent: Boolean;
                            bgColor32: TColor32;
                            filename: String;
                            compressionLevel: TCompressionLevel = 9;
interlaceMethod: TInterlaceMethod = imNone): boolean;
var  png: tPNGObject;
     FileStream: TFileStream;
begin
  result := false;
  try
    FileStream := TFileStream.Create(filename, fmCreate);
    try
png := Bitmap32ToPNG (sourceBitmap, false, transparent, WinColor(bgColor32),
                            compressionLevel, interlaceMethod);
      try
        png.SaveToStream (FileStream);
        result := true;
      finally
        png.Free;
      end;
    finally
      FileStream.Free;
    end;
  except
  end;
end;
*)

//********************************************************* // code example of loading and saving a PNG image file //--------------------------------------------------------- procedure PNGExample; var transparent: boolean;      myBitmap: tBitmap32; begin   myBitmap := TBitmap32.Create;   transparent := true;   if LoadPNGintoBitmap32 (MyBitmap, 'example1.png', transparent)   then begin     if transparent then       // add anything else that should be on transparent PNG image...       MyBitmap.DrawMode := dmBlend     else       MyBitmap.DrawMode := dmOpaque;
    SaveBitmap32ToPNG (myBitmap, transparent, clBlack, 'savetest.png', 5);   end;   myBitmap.Free; end;
begin   // PNGExample; // delete comment to test loading and saving PNG image end.

Message source

FYI: Phrase searches are enclosed in either single or double quotes
 
 
Originally created by
Tamarack Associates
Mon, 20 May 2024 21:14:01 UTC
Copyright © 2009-2024
HREF Tools Corp.