Question

Using this (test) code to read a tEXt chunk from a PNG:

procedure TForm1.Button1Click(Sender: TObject);
var
  PngVar: TPngImage;
  n: Integer;
begin
  PngVar := TPNGImage.Create;
  PngVar.LoadFromFile('C:\test.png');
  for n := 0 to pred(PngVar.Chunks.count) do
  if PngVar.Chunks.item[n].Name='tEXt' then
  with PngVar.Chunks.item[n] as TChunkTEXT do
  memo1.lines.add(KeyWord+'='+Text);
end;

The code is from an example by the original author of the TPNGObject and was downloaded from embercardo's website. KeyWord contains the value of what the tEXt chunk is, in this case comment. Text contains the text we need. It is an AnsiString and should have breaks in them but when casting from AnsiString to unicode they are lost and it becomes one string with not even a space between the end and start of a line.

Stepping through the debugger I noticed It had each line in single quotes and between the lines it has #$A which I assume if I check in hex are some form of control character.

comment=PunkBuster Screenshot (ñ) BF3 Levels/MP_017/MP_017'#$A'1135998 31.204.131.11:25530 GoTBF3.nl #4 | 32p | TDM Canals Only | 500 Tickets'#$A'geawtaw46y4w63a46a34643a BorislavFatsolka'#$A'Attempted: w=320 X h=240 at (x=50%,y=50%)'#$A'Resulting: w=320 X h=200 sample=1'

Sample Image http://www.pbbans.com/pbss_evidence/bf3/31.204.131.11:25530/5d00a95d22fae4a287bd510c076db1bf-2e36c3b4.png Here is the sample. What I am doing is reading data off punkbuster images to make them searchable in our communities database. But I also display the information next to the image and id like to have the line breaks and or know when the line ends.

When placed into memo or string list directly it comes out all one line like:

comment=PunkBuster Screenshot (ñ) BF3 Levels/MP_017/MP_0171135998 31.204.131.11:25530 GoTBF3.nl #4 | 32p | TDM Canals Only | 500 Tickets*geawtaw46y4w63a46a34643a* BorislavFatsolkaAttempted: w=320 X h=240 at (x=50%,y=50%)Resulting: w=320 X h=200 sample=1

Question

What is the best way to handle this ansistring which is what it is from the original image and or TPNGImage no real choice there. Putting it into a memo, rich edit or string list with the breaks intact.

The first thing that comes to mind is probably inefficient and thats just to throw it into a byte array or the like and read it byte by byte cutting each line at the end of line marks.

More Data from the example You should be able to see this by downloading the example image but, this is how it looks in a hex editor (First part of the file intact, png header, tEXt chunk header keyword etc.

‰PNG........IHDR...Ž...2.....ûŒÆ$....tEXtcomment.PunkBuster Screenshot (ñ) BF3  Levels/MP_017/MP_017.1135998 31.204.131.11:25530 GoTBF3.nl #4 | 32p | TDM Canals Only | 500 Tickets.*geawtaw46y4w63a46a34643a* BorislavFatsolka.Attempted: w=320 X h=240 at (x=50%,y=50%).Resulting: w=320 X h=200 sample=1.

89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 02 8E 00 00 01 32 08 02 00 00 00 FB 8C C6 24 00 00 01 03 74 45 58 74 63 6F 6D 6D 65 6E 74 00 50 75 6E 6B 42 75 73 74 65 72 20 53 63 72 65 65 6E 73 68 6F 74 20 28 F1 29 20 42 46 33 20 20 4C 65 76 65 6C 73 2F 4D 50 5F 30 31 37 2F 4D 50 5F 30 31 37 0A 31 31 33 35 39 39 38 20 33 31 2E 32 30 34 2E 31 33 31 2E 31 31 3A 32 35 35 33 30 20 47 6F 54 42 46 33 2E 6E 6C 20 23 34 20 7C 20 33 32 70 20 7C 20 54 44 4D 20 43 61 6E 61 6C 73 20 4F 6E 6C 79 20 7C 20 35 30 30 20 54 69 63 6B 65 74 73 0A 2A 67 65 61 77 74 61 77 34 36 79 34 77 36 33 61 34 36 61 33 34 36 34 33 61 2A 20 42 6F 72 69 73 6C 61 76 46 61 74 73 6F 6C 6B 61 0A 41 74 74 65 6D 70 74 65 64 3A 20 77 3D 33 32 30 20 58 20 68 3D 32 34 30 20 61 74 20 28 78 3D 35 30 25 2C 79 3D 35 30 25 29 0A 52 65 73 75 6C 74 69 6E 67 3A 20 77 3D 33 32 30 20 58 20 68 3D 32 30 30 20 73 61 6D 70 6C 65 3D 31 0A

Other Findings If I dump the Chunk (PngVar.Chunks.item[n].SaveToStream) it gives me basically what we find in the hex editor. The control characters are 0A. I am not sure if the #$A is a before or after conversion effect maybe even being caused by the pngimage code.

Was it helpful?

Solution

Try:

memo1.lines.add(KeyWord+'='+StringReplace(Text,#10,sLineBreak,[rfReplaceAll]));

OTHER TIPS

Another approach would be Jedi CodeLib

sl := TJclStringList.Create;
sl.Split(Text, #10);
sl[0] := 'Keyword=' +sl[0]
memo1.lines.AddStrings(sl);
sl.Free;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top