Recent

Author Topic: Writing PNG images using streams fails in V2.0 when targeting .ods format.  (Read 316 times)

Russ

  • Newbie
  • Posts: 2
There is an issue when writing PNG images to worksheets using streams in V2.0 that didn't manifest in V1.16:

When PNG image(s) are written to a sheet using a stream through the TsWorkSheet.WriteImage() and the resultant workbook is then written to disk in .ods format, when attempting to open the document in Libre Office Calc, a read error "Format error discovered in the file in sub-document content.xml at 1,4468(row,col)" is thrown. When the image is written using the File version of the TsWorksheet.WriteImage() function where the image is loaded from a PNG file, then everything works. There are no problems with .xlsx format.

The .ods archives were unpacked and the problems found are the following:
  • In the Picture directory there are no images.
  • In content.xml the field <draw:image xlink:href="Pictures/" has no images listed.
  • manifest.xml has the same problem.
In addition, if the user (me :D ) uses the same stream to load multiple images and forgets to clear the stream between loading images, then the application hangs. There is a fix that stops the app from hanging, but won't stop the wrong image from being loaded.
   
A patch is attached.

The test project:
Code: Pascal  [Select][+][-]
  1. program project1;
  2. uses
  3.   SysUtils, Classes, Graphics, LCLIntf, fpSpreadsheet, fpsTypes, fpsallformats;
  4. var
  5.   wbook: TsWorkbook;
  6.   wsheet: TsWorksheet;
  7.   image1: TPortableNetworkGraphic;
  8.   image2: TPortableNetworkGraphic;
  9.   astream: TMemoryStream;
  10.  
  11. begin
  12.   wbook := TsWorkbook.create;
  13.   image1 := TPortableNetworkGraphic.Create;
  14.   image2 := TPortableNetworkGraphic.Create;
  15.   astream:= TMemoryStream.Create;
  16.   try
  17.     (* In the target application the image is created by the app and not loaded from a file. *)
  18.     image1.LoadFromFile('Image1.png');
  19.     image2.LoadFromFile('Image2.png');
  20.  
  21.     (* Writing the image to the sheet directly from a file works for both .ods and .xlsx formats. *)
  22.     //wsheet := wbook.AddWorksheet('Image1');
  23.     //wsheet.WriteImage(0, 0, 'Image1.png');
  24.     //wsheet := wbook.AddWorksheet('Image2');
  25.     //wsheet.WriteImage(0, 0, 'Image2.png');
  26.     //wbook.WriteToFile('Test1_WriteImage(File).xlsx', true);
  27.     //wbook.WriteToFile('Test1_WriteImage(File).ods', true);
  28.     //wbook.clear;
  29.  
  30.     (* Copying a spreadsheet containing the image from excel to calc format works. *)
  31.     //wbook.ReadFromFile('Test1_WriteImage(File).xlsx');
  32.     //wbook.WriteToFile('Test2_SpreadsheetCopy.ods', true);
  33.  
  34.     (*
  35.       Writing the image to the sheet using a stream works on V1.16, but not on V2.00.
  36.       Attempting to open image_03.ods in Calc results in an error:
  37.       Format error discovered in the file in sub-document content.xml at 1,4466(row,col).
  38.     *)
  39.     wbook.Clear;
  40.     wsheet := wbook.AddWorksheet('Image 1');
  41.     image1.SaveToStream(astream);
  42.     wsheet.WriteImage(0, 0, astream, 1.0, 1.0);
  43.     wsheet := wbook.AddWorksheet('Image 2');
  44.  
  45.     astream.Clear; // If this was forgotten, the application used to hang - now loads Image1 for Image2.
  46.     image2.SaveToStream(astream);
  47.     wsheet.WriteImage(0, 0, astream, 1.0, 1.0);
  48.     wbook.WriteToFile('Test3_WriteImage(Stream).xlsx', true);
  49.     wbook.WriteToFile('Test3_WriteImage_01(Stream).ods', true);
  50.  
  51.     OpenDocument('Test3_WriteImage_01(Stream).ods');
  52.  
  53.   finally
  54.     wbook.Free;
  55.     image1.Free;
  56.     image2.Free;
  57.     astream.Free;
  58.   end;
  59. end.
« Last Edit: September 23, 2025, 03:56:26 pm by Russ »

wp

  • Hero Member
  • *****
  • Posts: 13195
Re: Writing PNG images using streams fails in V2.0 when targeting .ods format.
« Reply #1 on: September 23, 2025, 10:16:10 pm »
Thanks for analyzing the situation and providing a patch. Applied to ccr-svn.

 

TinyPortal © 2005-2018