Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Feature request: How about an event for making the image object accessible #10

Closed
idw-git opened this issue Oct 4, 2022 · 3 comments
Closed

Comments

@idw-git
Copy link

idw-git commented Oct 4, 2022

I'm sorry for not finding a more proper subject for this, Angus, but here's what I was looking for, what I aready tried, and why I'm asking for an additional event:

  1. First thing was my intention to access the TPngImage object for adjusting its compression level since it might not be desirable to use compression in certain situations, for a discussion about this cf. here.
  2. Next I took a look at your subclassing feature as provided using the TImageFormat() class: Now here I may be wrong, but I couldn't get it to work without apparently having to provide a completely rewritten (resp. copied) image format class since I never got to the point where registering a class derived from an existing one would replace the already existing one since the registering routine immediately exits if it detects an attempt to register the new one for replacing an already existing one. IOW: Since the inherited ancestor class is always registered before registering the derived one there's currently no way to replace it - or am I doing something wrong here?
  3. So finally, that's why I'm coming up to make my suggestion: If the "subclassing" cannot achieve what I'm looking for, how about implementing a final OnSaveToStream() event exposing the TPngImage object (and similar for any other image type) for applying further type specific options without creating the need for you to provide various different access points depending on the respective image type's capabilities?

PS: For now I've just added a single line setting the desired compression level directly into your code, but that's note really the way I would prefer if there's a better one to be shared ...

				Michael

--
PGP Key ID (RSA 2048): 0xC45D831B
IERenderer's Home https://www.pmpgp.de/renderer/History.htm
S/MIME Fingerprint: 94C6B471 0C623088 A5B27701 742B8666 3B7E657C

@AngusJohnson
Copy link
Owner

AngusJohnson commented Oct 4, 2022

Hi again Michael and thank you for the helpful feedback.

Since the inherited ancestor class is always registered before registering the derived one there's currently no way to replace it - or am I doing something wrong here?

This seems to be the key issue.
If I changed format registrations so that later registrations of the same format replace the existing one, then wouldn't that solve this for you?

In Img32.pas and inside TImage32.RegisterImageFormatClass() update as per the follow:

  //avoid duplicates but still allow overriding
  for i := 0 to imageFormatClassList.count -1 do
  begin
    imgFmtRec := PImgFmtRec(imageFormatClassList[i]);
    if SameText(imgFmtRec.Fmt, ext) then
    begin
      //imgFmtRec.SortOrder := clipPriority; //todo: re-sort if priority changes 
      imgFmtRec.Obj := bm32ExClass; // replace prior class
      Exit;
    end;
  end;

@idw-git
Copy link
Author

idw-git commented Oct 5, 2022

If I changed format registrations so that later registrations of the same format replace the existing one, then wouldn't that solve this for you?

I think so, don't ask me why I didn't give it a try, I certainly should have. The only important issue would be to make sure that no further initialization routines are affected to begin with which cannot easily be undone during replacement. Otherwise it should work, I assume. I'll get back to you after doing some more tests with regard to my original goal.

AngusJohnson added a commit that referenced this issue Oct 5, 2022
SVG images were not being loaded in their native sizes with TImage32 was empty. (#9)
@idw-git
Copy link
Author

idw-git commented Oct 5, 2022

Well, I'm impressed, I really wasn't sure I could get it to work (since I'm not familiar with class instance inheritance), but yes, I could implement what I was looking for, here's just the image format declaration part of my PNGX unit:

type
  {$IFDEF FPC}
  TOnSaveToStream = procedure(png: TPortableNetworkGraphic) of Object;
  {$ELSE}
  TOnSaveToStream = procedure(png: TPngImage) of Object;
  {$ENDIF}
  TImageFormat_PNGX = class(TImageFormat_PNG)
  private
    class var FOnSaveToStream: TOnSaveToStream;
  public
    procedure SaveToStream(stream: TStream; img32: TImage32); override;
    class property OnSaveToStream: TOnSaveToStream read FOnSaveToStream write FOnSaveToStream;
  end;

So in short: I just had to modify the SaveToStream methods by adding a single line of code respectively for invoking the event exposing the proper png object and figure out how to exactly declare the required types. Thanks again for your excellent components!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants