Reading back text data added to PNG image

100 Views Asked by At

In my Delphi app I create a PNG file which also includes some text as key-value pairs:

procedure TFrmMain.SaveasPNG1Click(Sender: TObject);
var
  Png: TPngImage;
begin
  if SaveDialog1.Execute then
  begin
    Png := TPngImage.Create;
    try
      Png.Assign(Image1.Picture.Graphic);
      Png.AddtEXt('SomeKey', 'SomeValue'); // <-- adding text
      Png.SaveToFile(SaveDialog1.FileName);
    finally
      Png.Free;
    end;
  end;
end;

I can't seem to find any TPNGimage method to read the data back, however. Is there a way to read the data back in my app?

(I'm using Delphi 11 Alexandria)

1

There are 1 best solutions below

1
SilverWarior On BEST ANSWER

When you call Png.AddtEXt() a new data chunk of type TChunkTEXT is created and your data assigned to it.

You can retrieve such data back from the PNG by finding this data chunk using the Png.Chunks.FindChunk() method where you pass the TChunkTEXT class as parameter to the mentioned method. The code for retrieving such data would look like this:

var 
  TextChunk: TChunkTEXT;
  SomeKey, SomeValue: String;
begin
  ...
  TextChunk := TChunkTEXT(Png.Chunks.FindChunk(TChunkTEXT));
  SomeKey := TextChunk.Keyword;
  SomeValue := TextChunk.Text;

The only problem of the .FindChunk() method is that it only finds the first chunk matching the specified class - therefore you can retrieve only the first key-value pair even although it is possible to save multiple key-value pairs by calling Png.AddtEXt() multiple times.

In order to retrieve multiple key-value pairs from a PNG you will have to iterate through all chunks manually and retrieve data from text chunks. The code should look like this:

for I := 0 to Png.Chunks.Count-1 do
begin
  if Png.Chunks.Item[I] is TChunkTEXT then
  begin
    TextChunk := TChunkTEXT(Png.Chunks.Item[I]);
    Memo1.Lines.Add(TextChunk.Keyword + '=' + TextChunk.Text);
  end;
end;

PS: Yes the documentation on TPNGimage is a bit lacking but you can find how it works by peaking into the Vcl.Imaging.pngimage unit that ships with Delphi.