Am 24.06.2022 um 11:30 schrieb Mattias Gaertner via lazarus:
On Fri, 24 Jun 2022 11:09:17 +0200
Werner Pamler via lazarus<[email protected]>  wrote:

[...] It is
my impression there is no way to register a new format in any way
without modifying the sources of TPicture.
TPicture:
     class function SupportsClipboardFormat(FormatID: TClipboardFormat): 
Boolean;
     class procedure RegisterFileFormat(const AnExtension, ADescription: string;
       AGraphicClass: TGraphicClass);
     class procedure RegisterClipboardFormat(FormatID: TClipboardFormat;
       AGraphicClass: TGraphicClass);
     class procedure UnregisterGraphicClass(AClass: TGraphicClass);
     class function FindGraphicClassWithFileExt(const Ext: string;
       ExceptionOnNotFound: boolean = true): TGraphicClass;

Ah, of course. (I thought I had searched for "Register" in unit graphics...). Now I saw that Vampyre also uses these TPicture class methods to finally register their formats for TPicture. Thus, everything should be fine.

But still the situation is not very satisfying.

First observation after installing VampyreImagingPackageExt (the other package, VampyreImagingPackage, has no registration unit): I add TImage to a form and load the Lazarus "paw" to it. Works fine at designtime, but at runtime the image is empty. As the OP already noted Vampyre's TImagingPNG class is not found. This is because the Vampyre formats are registered only at designtime, but not at runtime of a project. But this can be fixed easily: After adding unit *ImagingComponents *to the uses clause, the "paw" is displayed at runtime, too.

Next complication comes into play if the user decides to uninstall Vampyre. The problem is that every graphic type writes its class name to the lfm file in front of the image data (Picture.Data). So, when a picture was loaded into TImage while Vampyre was installed all the images are brand-marked by the Vampyre classes, e.g. TImagingPNG rather than TPortableNetworkGraphic:

This is the part of the lfm written when Vampyre is installed (I am adding spaces to the hex data to see the digits:

  object Image1: TImage
    Left = 8
    Height = 344
    Top = 8
    Width = 456
    Picture.Data = {
      0B 54 49 6D 61 67 69 6E 67 50 4E 47 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 01 C6       11 T  I  m  a  g  i  n  g  P  N  G                // 11 is the length byte

An image written by the LCL without Vampyre contains this:

object Image1: TImage
    Left = 24
    Height = 284
    Top = 20
    Width = 376
    Picture.Data = {
      17 54 50 6F 72 74 61 62 6C 65 4E 65 74 77 6F 72 6B 47 72 61 70 68 69 63 9A 3D 00 00 89 50 4E 47       23 T  P  o  r  t  a  b  l  e  N  e  t  w  o  r  k  G  r a  p  h  i  c

When such a project is loaded into a Lazarus without Vampyre at first the VampyreImagingPackage and/or VampyreImagingPackageExt requirements must be removed from the project. But, of course, the Vampyre image class signatures are still in the lfm file, and the IDE refuses to load the form with this error:

    Unable to find the component class "TForm1".
    It is not registered via RegisterClass and no lfm was found.
    It is needed by unit:
D:\Prog_Lazarus\tests\_images\vampyre\format_registration\vampyre_stripped\unit1.lfm

I think this is the most confusing part of that issue. If it would say "Unable to find class "TImagingPNG"" it would be much clearer.

However, I don't think that much can be done against that. There is always a risk when using third-party components that irreversible changes could occur. Hmm, well, somebody could write a tool the fix the image classname header in the lfm's Picture.Data.

Werner

-- 
_______________________________________________
lazarus mailing list
[email protected]
https://lists.lazarus-ide.org/listinfo/lazarus

Reply via email to