TPNGImage

(TPNGImage contains all the properties and methods from the TBitmap)

Ö

TPNGImage


Methods

w

LoadFromStream

w

SaveToStream

w

LoadFromFile

w

SaveToFile

w

RegisterChunkClass

w

Assign

Properties

Ÿ

Chunks

Ÿ

Filter

Events

Ÿ

OnProgress
 

Ö

TChunkList


Methods

w

Add

w

Clear

w

IndexOf

w

Move

Properties

Ÿ

Count

Ÿ

Item

Ÿ

Owner
 

Ö

TChunk


Methods

w

Assign
virtual
w DoAction
protected

w

SaveToStream
virtual

Properties

Ÿ

ChunkType

Ÿ

Index

Ÿ

Size

Ÿ

Stream protected

Ÿ

Owner

Derivates from TChunk
(Contains all methods and properties from TChunk)

Ö

TChunkGama


Properties

w

Value
 

Ö

TChunkTEXT
TChunkZTXT


Proprieades

w Keyword

w

Value

Ö

TChunkPLTE


Properties

w Palette
Read-Only

Ö

TChunkIHDR


Properties

w BitDepth
w ColorType
w Compression
w Filter
w Height
w Interlaced
w Width

Ö

TChunkIDAT



Ö

TChunkIEND



 

 
help page 

 release notes for the PNG encoder and decoder for Delphi 5 version 1.2

This is version 1.2 of the encoder and decoder to the Portable Graphics Network format for Delphi 5. This implementation is capable of reading and saving images with Gamma correction and direct access to all the PNG chunks. This implementation was all worked on Delphi 5 and it can show images progressively, as it is being decoded.

The unit was tested in all the images Willem van Schaik test page, and, it worked with 100% of the images.

TPNGImage>TBitmap>TGraphic>TObject>TPersistent

 Component to implement the PNG format

This is the main component that implements the decoder and encoder for PNGs. The component is based on TBitmap meaning it have all TBitmap properties and methods. It is possible to use the Assign procedure to copy the contents from most of TGraphic descendents like TJPEGImage, etc..

TPNGImage.LoadFromStream

 procedure LoadFromStream(Stream: TStream)

Use the LoadFromStream to load a PNG file from any class derivate from TStream like TMemoryStream or TFileStream.

The method will read all the chunks until it find the IEND chunk. If the OnProgress event is set, using additional code, the image may be displayed progressively (with a loss of speed).

 Example on how using the method.

{The method bellow opens the image X.PNG }
{and put it on the background of the     }
{current window. Note that this method   }
{makes the same work that LoadFromFile do}
var
  PNG: TPNGImage;
  FStream: TFileStream;
begin
  PNG := TPNGImage.Create;
  try
    FStream := TFileStream.Create('X.PNG',fmOpenRead);
    PNG.LoadFromStream(FStream);
    Form1.Canvas.Draw(0, 0, PNG);
  finally
    PNG.Free;
    FStream.Free;
  end;
end;

 See also:

LoadFromFile
SaveToFile
SaveToStream

TPngImage.SaveToStream

 procedure SaveToStream(Stream: TStream)

SaveToStream saves the current image from the TPNGImage object to a class derivate from TStream like TFileStream or TMemoryStream.

All the chunks from the previous loaded image will be mantained, with modifications to the necessary chunks.

Also, the filter property is important to set which filters maybe used to save the image.

 See also:

SaveToStream
LoadFromFile
LoadFromStream

TPngImage.LoadFromFile

 procedure LoadFromFile(const FileName: String)

LoadFromFile loads a png file from a file specified by the parameter. The image will be readed until the IEND chunk is found or until the end of the file (some applications like the current version of ACDSee for a bug does not add the IEND chunk).

 See also:

SaveToStream
SaveToFile
LoadFromStream

TPNGImage.SaveToFile

 procedure SaveToFile(const FileName: String)

SaveToFile saves the current image to a file. The method uses the SaveToStream procedure to save the image.

 See also:

SaveToStream
LoadFromFile
LoadFromStream

TPNGImage.RegisterChunkClass

  TChunkType = Array[0..3] of Char;
  TChunkClass = class of TChunk;
  procedure RegisterChunkClass(ChunkType: TChunkType; 
    ChunkClass: TChunkClass)

This procedure will probably not be used. It is used mainly internally for upgrade reasons to support new chunk types.

When the method TChunkList.Add(Stream: TStream) is called, the procedure look for registered chunk classes by this method in an internal chunk list. If the chunk read is registered, it will create a new chunk class based on the registered to do special work when the class is being saved or readed.

To create a new class it is necessary to declare a class based on TChunk and in the ChunkType field use a name with 4 letters.

The Portable Graphics Network have some conventions when naming new chunks:

Letter

What means if the letter case is:

Uppercase

Lowercase

1

The chunk is critical to the image be decoded

The chunk is not critical to the image be decoded.

2

The chunk is public and is in the PNG specification. The chunk is private and is used only by a specific application.

3

Must be in uppercase. Can not be in lowercase.

4

The chunk is safe to be copied in case there is any modification in the image. The chunk should be removed in case there are any modifications in the image.

In the new class created it is possible to modify the procedures Assign, SaveToStream and DoAction using override in the declaration to add specific actions when the chunk is copied, saved or readed.
TPNGImage.Assign

 procedure Assign(Source: TPersistent)

The Assign procedure copies the content from another TPNGImage or derivates from TGraphic as TBitmap, TJPEGImage.

 Example on how using the procedure.

{The method bellow convert from TJPEGImage}
{to TPNGImage and saves the file. Include }
{jpeg in the application uses}
var
  JPEG:TJPEGImage;
  PNG :TPNGImage;

begin
  JPEG := TJpegImage.Create;
  PNG := TPNGImage.Create;
  try
    JPEG.LoadFromFile('Picture.JPG');
    PNG.Assign(JPEG);
    PNG.SaveToFile('Picture.PNG');
  finally
    JPEG.Free;
    PNG.Free;
  end;
end;

TPNGImage.Chunks

 property Chunks: TChunkList;

Use the Chunks property to have direct access to all the chunks from the TPNGImage. Chunks are "pieces" of essential and non essential information for the image. For instance, the IHDR chunk contains information about the image size, color type, interlace, type, etc...
The IDAT chunk contains the image itself and will be decoded automatically.
The IEND chunk indicates the end of the file.

TPNGImage.Filter

 TEncodeFilter = (efNone, efSub, efUp, efAverage, efPaeth))
   TEncodeFilterSet = set of TEncodeFilter

    property Filter: TEncodeFilterSet;

The filter property indicates which filters will be applied before the image is compressed. It is allowed to set the property as Filter := [efNone, efSub, efUp, efAverage, efPaeth] to always make sure to use the best filters to each line (with a performace loose).

Each line in the PNG may use a different filter, and the encoder will test all the filters in the property to test which one is better.

TPNGImage.OnProgress

 TProgressStage = (psStarting, psRunning, psEnding)
   TProgressEvent = procedure (Sender: TObject; Stage: TProgressStage;
     PercentDone: Byte; RedrawNow: Boolean; const R: TRect; const Msg: string)
     of object;

   property OnProgress: TProgressEvent

The OnProgress event receives progress information as the image is being decoded. This event is useful for displaying the image progressively.

For more information about this event, take a look on the Delphi Help (TGraphic.OnProgress).

 Example on how using the event:

{The method bellow reads an images and   }
{display it as it is being readed        }

procedure TForm1.Progresso(Sender: TObject; Stage:TProgressStage;  PercentDone: Byte; RedrawNow: Boolean;  const R: TRect; const Msg: string
var
  PNG: TPNGImage;

begin
 PNG := TPNGImage(Sender);
 {If it is a TPNG image we can show it progressive}

  if (PercentDone mod 5 = 0) and
  (TChunkIHDR(PNG.Chunks[0]).Interlaced = 0) then
begin
BitBlt(Canvas.Handle, (Width - PNG.Width) div 2,
((Height - PNG.Height) div 2) + LastPos,
R.Right, R.Bottom - LastPos,
PNG.Canvas.Handle, 0, LastPos, SRCCOPY);
LastPos := R.Bottom;
end
else if (TChunkIHDR(PNG.Chunks[0]).Interlaced = 1) then
Canvas.Draw((Width - PNG.Width) div 2, 
((Height) - PNG.Height) div 2, PNG);
end;

Application.Processmessages;

end;

TChunkList>TObject

 Mananges all the chunks in the image

The TChunkList component allows access to all the chunks in the image. Using methods in this component allows to access, add, remove and manage all the chunks.

Chunks are "pieces" of essential and not essential information for the image. For instance, the chunk IHDR contains information about the image dimension, color type, interlace type, etc...
The chunk IDAT contains the image itself and it will be decoded automatically.
The IEND chunk indicates the end of the file.

 

TChunkList.Add

 function Add(Item: TChunk): TChunk;

This Add declaration add an existent chunk to the end of the list. Although this item must exist. It will return the same item from the parameter.

 function Add(ChunkClass: TChunkClass): TChunk;

This declaration creates a new item using the class from the parameter and add it to the list. It will return the item created.
ex:

PNG.Chunks.Move(PNG.Chunks.Add(TChunkTEXT).Index, PNG.Chunks.Count - 2);

 function Add(Stream: TStream): TChunk;

This declaration of the Add method is only used internally. It reads the chunk from the Stream and add the item to the list. The function returns the chunk created from the Stream.

TChunkList.Clear

 procedure Clear;

This method clears all the items in the list. It is not recommended to call this method unless you intend to create the essential chunks before saving the image.

TChunkList.IndexOf

 function IndexOf(Chunk: TChunk): Integer

This declaration of IndexOf returns the position of the chunk in the parameter. If it is not in the list, it will return -1.

 function IndexOf(ChunkClass: TChunkClass): Integer

This declaration of IndexOf returns the position of the first chunk with the specified class in the parameter. If none item is found, it returns -1.

TChunkList.Move

 procedure Move(Index1, Index2: Integer)

The procedure Move moves the position of a chunk in the list. Index1 is the position of the chunk to move and index2 is the new position.

TChunkList.Count

 property Count: Integer;

The property chunk returns the number of chunks in the list.

TChunkList.Item

 property Item[Index: Integer]: TChunk

The property Item returns a chunk from the list. As the property is default, it is possible to access this property with TChunkList object, ex: PNG.Chunks[0].Index.

Its also possible to typecast the returned chunk to access it specific property in case there is a known derived chunk class.

 Exemplo de uso do método.

{The method bellow, looks for the first    }
{TEXT chunk and shows it contains          }

procedure Exibe(Arquivo: String);
var
  PNG: TPNGImage;
  POSI: Integer;
  TEXT: TChunkTEXT;
begin
  PNG := TPNGImage.Create;
  PNG.LoadFromFile(Arquivo);
  POSI := PNG.Chunks.IndexOf(TChunkTEXT);

  If POSI = -1 THEN
  begin
   showmessage('There are no TEXT chunk in the image.');
  exit;
  end;
  TEXT := TChunkTEXT(PNG.Chunks[Posi]);
  
  showmessagefmt('Keyword: %s%s Valor: %s',
    [TEXT.Keyword, #13#10#13#10, TEXT.text]);
  PNG.Free;
end;

TChunkList.Owner

 property Owner: TPNGImage

The property returns the TPNGImage owner that contains this TChunkList.

TChunk>TObject

 Class for unknown chunks or base class for known

This class contains information for a chunk in the image.  There are various classes that derivates from TChunk like TChunkIHDR, TChunkIDAT, TChunkTEXT, etc... that are implementations for known chunks. You may use typecast the TChunk to access declared methods and properties from the derivate classes.

It is not necessary to access the TChunk and derivates unless you need to access specifics operations from the Portable Graphics Network format.

All the data from the stream are declared in the "Stream", a protected property that allows direct access to the data. Only descendents classes may access this property and it is intended to be used in the creation of new TChunk classes.

TChunk.Assign

 procedure Assign(Source: TPersistent); virtual;

This method is used internally to copy the contents from another chunk with the same class into the current one.

In case you are creating a descendent class from TChunk is recommended to override this class to copy additional properties that the class may store.

TChunk.DoAction

 procedure DoAction; virtual;

The DoAction method is automatically for each chunk as soon as the decoder finishes reading all the chunk. This procedure is declared as protected and may only be accessed by TChunk descendent classes.

When creating a new TChunk class it is essential to override this method if the chunk modifies the image.

TChunk.SaveToStream

 procedure SaveToStream(Stream: TStream); virtual;

The method SaveToStream saves the chunk content in a stream. This method is normally used internally and may be overridden in descendents TChunk classes to make additional operations (usually cleaning the Stream and writing the code all over again). The method calculates and add the CRC code automatically. 

TChunk.ChunkType

 TChunkType = Array[0..3] of Char
   property ChunkType: TChunkType

The property returns the chunk kind for the current chunk.

TChunk.Index

 property Index: Integer

The property index, returns the position of the current chunk from the list in the TChunkList owner.

TChunk.Size

 property Size: Integer

The property size returns the size of the stream (Stream.size), which is the chunk data.

TChunk.Stream

 property Stream: TMemoryStream

The stream property is declared as protected in the TChunk declaration meaning it can't be accessed directly, but only from descendents of TChunk.

The property gives direct access to the Chunk contents and may be modified normally as a TMemoryStream (see Delphi Help).

This property is important only to create new chunk types as it gives access to the data.

TChunk.Owner

 property Owner: TChunkList

The owner property returns the TChunkList that contains the current chunk.

TChunkGamma > TChunk > TObject

 Controls the image color intensity

The chunk gamma (gAMA), defines the intensity for the output. As in different operational systems, or in different environments, the intensity of the same RGB color may be different, the Portable Graphics Network specification defines a chunk gAMA to correct the intensity. The decoder already do all the work when it is decoding the image, but it is possible to get the value calling the property value.

TChunkGamma.Value

 property Value: Cardinal

The property Value, returns the Gamma value from the chunk. To calculate the real value, you should divide the value from this property by 100000 (using an appropriate variable kind like double, float, real...)

TChunkText > TChunk > TObject
TChunkZTXT > TChunk > TObject

 Contain additional text information about the image

The difference between the chunks TChunkText (tEXT) and TChunkZTXT (zTXT) is that the second one is compressed meaning that, if the text is large, it will use less memory.

Booth the chunks have the same properties and they are used to add extra comments to the image (like in GIF), such as the image creator, etc..

TChunkText.Keyword
TChunkZTXT.Keyword

 property Keyword: String

The property Keyword indicates the meaning of the field value. For instance, let's suppose you want to put a comment on how the image was created. You could then put "Image creation" on the Keyword field.

TChunkText.Value
TChunkZTXT.Value

 property Value: String

The Value property indicates the text value for the keyword. There are no limits for the size, but it is recommended to use the TChunkZTXT in case the text is big.

TChunkPLTE>TChunk>TObject 

 Palette for indexed mode or recommended palette

The TChunkPLTE (PLTE) palette is critical in case the color mode is indexed (each pixel indicates a palette index). It contains the possible colors that the pixels may use.
In case the color mode is RGB, the palette is a recommended palette to use.

TChunkPLTE.Palette

 property Palette: HPalette

This is a read-only property. This property creates a palette using WIN32API and returns its handle (hPalette).

To modify the paletty being used by the current image, it is necessary to change the property Palette from the TPNGImage. (what requeries creating a new palette using WIN32API).

This method is used main internaly and it does not always correspond to the current palette used by the images. It is recommended to use the property Palette from TPNGImage.

TChunkIHDR > TChunk > TObject

 Contains important information about the image

TChunkIHDR (IHDR) is obligatorily the first chunk in the image and contains information about the image dimension, the color mode, interlace type, compression method, and set of filters.

Although most of the properties are transfered to the TPNGImage, some information from this chunk may have some importance.

Modification in this chunk does not modify the image and they will be overriden when the image is saved.

TChunkIHDR.BitDepth

 property BitDepth: Byte

This property indicates how many bits each sample has. 

If ColorType value is Palette, this property can be 1, 2, 4 or 8. This means that each pixel will have this number of bits. 

In case the image is Grayscale, this property may be 1, 2, 4, 8 or 16. If the value is 0, the pixel color is black, if the value is 2^BitDepth, the color is white.

In case the ColorType is RGB, this property can be 8 or 16, and each pixel has 3 values with the number of the bits corresponding the bitdepth. The values indicates Red, Green, Blue, or known as RGB. The mix of these 3 values results in almost any color.

In case the image is RGBALPHA or GRAYSCALEALPHA, the value can be 8 or 16. RGBALPHA works like RGB, but with an extra value, alpha, indicating the transparency. The same thing happens with GRAYSCALEALPHA and GRAYSCALE.

Note: In case the bitdepth is 16, it will be reduced to 8 due to incompability with windows and with current video adpters. This although doesn't affect visually the image.

TChunkIHDR.ColorType

 property ColorType: Byte

The colortype property indicates the color mode being used in the current image. The supported values are:

0 - (Grayscale) Means that the image uses grayscale tons
1 - (RGB) Each pixel in the image has 3 values RGB
3 - (Palette) Each sample correspond to a palette color
4 - (GrayscaleAlpha) Grayscale with an alpha value
5 - (RGBAlpha) Pixel with 3 RGB values and one alpha

TChunkIHDR.Compression

 property Compression: Byte

There is currently only one possible value for this property, 0. As in Portable Graphics Network specification it means that the image uses ZLIB compression method for compressing the images. It was added for future expansions in PNG.

TChunkIHDR.Filter

 property Filter: Byte

This property indicates the set of filters, that are operations made to the image bytes before it is compressed, to get a better compression.

Currently, only the value 0, adaptive filtering with 5 basic filters is supported by PNG specification. In case the decoder finds any other value, it will report an error. 

TChunkIHDR.Height

 property Height: Cardinal

Returns the image height (pixels). It is not recommended to use this value because it will not be updated when the image is changed.

To get the Height, use the property TPNGImage.Height.

TChunkIHDR.Interlaced

 property Interlaced: Byte

The interlaced property in the current PNG specification provides two values:

0 - No interlacement is used
1 - ADAM7 interlacement

Interlacing is a technique used to show the image contents progressively in a better way using a different transmission method.

TChunkIHDR.Width

 property Width: Cardinal

Returns the width (pixels) from the readed image. It is not recommended to use this value because it value will not be updated when the image is changed.

To get the Width, use the TPNGImage.Width property.

TChunkIDAT > TChunk > TObject

 Contain the file image

The TChunkIDAT (IDAT) is the main chunk and contains the compressed image. This chunk is decoded automatically by TPNGImage decoder.

TChunkIEND > TChunk > TObject

 End of the file

The IEND chunk indicates the end of the PNG file.