[Lazarus] Strange issue with TImage and lazarus 2.2.2

Werner Pamler werner.pamler at freenet.de
Fri Jun 24 17:27:13 CEST 2022

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<lazarus at lists.lazarus-ide.org>  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:

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.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20220624/4e75f1c0/attachment.htm>

More information about the lazarus mailing list