Page 1 of 1

Error loading image saved with XML

Posted: Wed Jun 15, 2022 1:26 pm
by edwinyzh
I'm still new to TRichViewEdit. Error happens when loading a document with a png image. I don't know if it matters, but the document's saved in XML.

Call stack:

Code: Select all

exception class    : EAccessViolation
exception message  : Access violation at address 00BEB480 in module 'program1.exe'. Read of address 00000050.

main thread ($28a8):
00beb480 +004 program1.exe RVGrHandler         1119   +0 TRVGraphicHandler.CreateGraphic
00e651a8 +140 program1.exe RVXMLRoutines        791  +25 DoReadImage
00e658fa +012 program1.exe RVXMLRoutines        901   +1 ReadImage
00e6b200 +160 program1.exe RVXMLRoutines       2348  +29 LoadRVDataFromXML
00e7eb85 +431 program1.exe RVXMLRoutines       7386 +104 RVLoadFromXML
00e81f0b +123 program1.exe RichViewXML          677  +43 TRichViewXML.DoLoadFromXML
00e817f9 +085 program1.exe RichViewXML          455  +11 TRichViewXML.DoLoadFromStream
00e8185a +002 program1.exe RichViewXML          463   +0 TRichViewXML.LoadFromStream
Breakpoint in the IDE in debug mode:
Image

Re: Error loading image saved with XML

Posted: Wed Jun 15, 2022 4:14 pm
by Sergey Tkachenko
In order to read a graphic class from XML, it must be registered, such as:
RegisterClasses([TPngImage]);

PS: for RVF, this limitation was removed. If a class is not registered, it is detected by content.
In the next update, I'll make the same for RichViewXML.

Re: Error loading image saved with XML

Posted: Thu Jun 16, 2022 3:34 am
by edwinyzh
Sergey Tkachenko wrote: Wed Jun 15, 2022 4:14 pm RegisterClasses([TPngImage]);
This doesn't work, I still get the very same error.

I also tried the following but it still doesn't work...

Code: Select all

RVGraphicHandler.RegisterPngGraphic(TPngImage);

Re: Error loading image saved with XML

Posted: Thu Jun 16, 2022 10:43 am
by Sergey Tkachenko
Please send me this XML file.

Re: Error loading image saved with XML

Posted: Thu Jun 16, 2022 2:32 pm
by edwinyzh
Just sent from email ;)

Re: Error loading image saved with XML

Posted: Thu Jun 16, 2022 5:35 pm
by Sergey Tkachenko
In this XML file, PNG file was created using TPNGGraphic, not TPNGImage,
So you need to call
RegisterClasses([TPNGGraphic]).

Re: Error loading image saved with XML

Posted: Sat Jun 18, 2022 11:27 am
by edwinyzh
Oh, it seems that my program uses TPNGGraphic from GraphicEx, but that graphic class has issue when TRichView loads the png file, the error happened within GraphicEx. So I went ahead and removed the GraphicEx dependency, png image loading in side TRichViewEdit seems to be working now.

Thanks!

Re: Error loading image saved with XML

Posted: Wed Jun 29, 2022 6:30 am
by edwinyzh
Hi Sergey,

Can we configure TRichView to use a fixed TGraphic class for loading png?

Now I just found out that the png images are saved to xml with TdxPNGImage from DevExpress, which is not what I want...

We need a way to control which graphic class to use when loading png, jpg, and so on, because I have DevExpress registers TdxPNGImage (TPicture.RegisterFileFormat and RegisterClasses) in the unit's initialization section.

And now I suspect TdxPNGImage is the source of this issue: Picture set to 80% but become very very large after exported to .docx or .rtf (update: after ensuring the png images are persisted using TPngImage, this issue still exist, so the graphic class shouldn't be related to that issue)

Update 1: So I did a GExperts Grep search into my library folders, many other including FastReport and JVL, also TPicture.RegisterFileFormat...

Extended question - now that since the png file is persisted with TdxPNGImage, what will hapeen if I remove TdxPNGImage from the projec and use TPngImage or other png graphic class instead? Will my document saved in xml failed to load?

Update 2: I found David Heffernan's code which allows me to list all registered TGraphic classes. Start from there, I think we can achieve prioritizing a TGraphic-derived class over another one for any given file extension, for example, .png.

Thanks.

Re: Error loading image saved with XML

Posted: Wed Jun 29, 2022 9:35 am
by edwinyzh
OK, based on David Haffernan's code, I seem to be able to achieve the goal of forcing TPicture.LoadFromFile to use the specified TGraphicClass. Feel free to comment:

Code: Select all

function GetLastRegisteredGraphicClassForFileExt(aFileExt: string): TGraphicClass;
var
  GetListProc: TReturnTList;
  L: TList;
  i: Integer;
begin
  if aFileExt[1] = '.' then
    Delete(aFileExt, 1, 1);

  FindGetFileFormatsFunc(GetListProc);
  if not Assigned(GetListProc) then
    Exit(nil);

  L := GetListProc;

  for i:= L.Count - 1 downto 0 do
    if SameText(PFileFormat(L[i])^.Extension, aFileExt) then
      Exit(PFileFormat(L[i])^.GraphicClass);
end;

function EnsureGraphicClassIsUsedFor(aFileExt: string; const aGraphicClass: TGraphicClass; const
    aFileFmtDesc: String): TGraphicClass;
var
  grClass: TGraphicClass;
begin
  if aFileExt[1] = '.' then
    Delete(aFileExt, 1, 1);

  grClass := GetLastRegisteredGraphicClassForFileExt(aFileExt);
  if (grClass = nil) or (grClass <> aGraphicClass) then
    TPicture.RegisterFileFormat(aFileExt, aFileFmtDesc, aGraphicClass);
end;

Re: Error loading image saved with XML

Posted: Wed Jun 29, 2022 1:08 pm
by Sergey Tkachenko
Here is the updated source code of RichViewXML:
https://www.trichview.com/support/files ... xmlpas.zip

Replace files in <TRichView Dir>\RvXML\Source\
Then you can recompile the packages (the simplest way is running "Install TRichView in Delphi IDE" in Windows Start menu).

This version includes the fixes that we discussed.

As for pictures. Now, the same procedure is applied both for RVF and XML files.

The default behavior: trying to use a graphic class specified in a file. If this class is not available/registered, detecting class by content.

You can modify it by including rvfoIgnoreGraphicClasses in RVFOptions. In this mode, a graphic class specified in a file is ignored, graphic class is detected by content.

Now, what is "graphic class is defined by content"?

1) When loading graphic from a stream, RVGraphicHandler.LoadFromStream method is used (RVGrHandler.pas)
This method tries to detect a graphic type by content (currently, it can detect Bitmap, Icon, Metafile, JPEG, PNG, GIF, TIFF, AnyMap, SVG), and choose a graphic class selected for this format. By default, a class for Png is TPNGImage. You can assign another class for PNG by calling RVGraphicHandler.RegisterPngGraphic(<png class>).

2) When loading from a file, RVGraphicHandler.LoadFromFile method is used.
This method tries two approaches.
First, it loads using TPicture.LoadFromFile, which uses associations between graphic classes and file extensions (TPicture.RegisterFileFormat)
If loading failed, it uses RVGraphicHandler.LoadFromStream, see above.
Now I think that these approaches must be swapped: first we should use RVGraphicHandler.LoadFromStream, and use TPicture.LoadFromFile only if it fails. This change will be included in the next TRichView update.

Re: Error loading image saved with XML

Posted: Wed Jun 29, 2022 2:28 pm
by edwinyzh
Thank you Sergey.

Is the update include changes for "Picture set to 80% but become very very large after exported to .docx or .rtf" ?

Because my initial research indicates it has something to do with the xml saving of the image width/height.

Re: Error loading image saved with XML

Posted: Wed Jun 29, 2022 2:54 pm
by Sergey Tkachenko
Yes, it includes these changes