ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 How to make MIO load first frame of MultiFrame?

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
PeterPanino Posted - May 25 2021 : 19:48:30
MIO.LoadFromFile and MIO.LoadFromFileAuto automatically load all frames from a Multi-Frame file (ICO, GIF, ...).

How can I prevent this in some special cases and make MIO load only the first frame of a Multi-Frame file (or the largest frame from an ICO file)? Is there a built-in function or parameter for this?
8   L A T E S T    R E P L I E S    (Newest First)
PeterPanino Posted - May 28 2021 : 05:58:25
Hi Nigel,

I have added another optimization to this test project - now in the preview the frame can be selected with the next/previous buttons (and with the PageUp/PageDown/Home/End keys), and the frame number is shown in the preview status bar:



attach/PeterPanino/202152855632_MIOLoadFirstFrame_v4.zip
738.42 KB
xequte Posted - May 27 2021 : 20:01:33
Hi Peter

I have added the LoadLargestFrameFromIco() method to the documentation.

Nigel
Xequte Software
www.imageen.com
PeterPanino Posted - May 27 2021 : 18:34:44
Hi Nigel,

if you want you can use it as a demo for your library.
xequte Posted - May 27 2021 : 18:12:09
Thanks Peter, your code looks good and I don't have any suggestions for optimization.

Nigel
Xequte Software
www.imageen.com
PeterPanino Posted - May 26 2021 : 09:53:38
It is a lot of fun writing code with the ImageEn library!
PeterPanino Posted - May 26 2021 : 09:42:27
So the problem is now solved:


procedure TForm1.LoadSingleFrameFromMultiFrameFiles;

  procedure LoadLargestFrameFromIco(const aIcoFile: string);
  var
    B: TIEBitmap;
    P: TIOParams;
    LargestFrame, LargestFrameIndex, WxH, FrameCount: Integer;
    i: Integer;
    ThisImage: Integer;
  begin
    B := TIEBitmap.Create;
    P := TIOParams.Create;
    try
      if P.Read(aIcoFile) then
      begin
        LargestFrameIndex := 0;
        FrameCount := P.ImageCount;
        if FrameCount > 1 then
        begin
          LargestFrame := 0;
          for i := 0 to FrameCount - 1 do
          begin
            WxH := P.ICO_Sizes[i].Width * P.ICO_Sizes[i].Height;
            if WxH > LargestFrame then
            begin
              LargestFrame := WxH;
              LargestFrameIndex := i;
            end;
          end;
        end;

        P.ImageIndex := LargestFrameIndex;
        B.Read(aIcoFile, P);
        ThisImage := mimgTest.AppendImage();
        mimgTest.SetImage(ThisImage, B);
        mimgTest.ImageTopText[ThisImage] := ExtractFileName(aIcoFile) + ' (Frame #' + IntToStr(LargestFrameIndex + 1) + '/' + IntToStr(P.ImageCount) + ')';
        mimgTest.ImageInfoText[ThisImage] := IntToStr(B.Width) + ' x ' + IntToStr(B.Height);
        FImagePaths.Add(aIcoFile);
      end;
    finally
      P.Free;
      B.Free;
    end;
  end;

  procedure LoadImage(const aImageFile: string);
  var
    P: TIOParams;
    ThisImage, FrameCount: Integer;
    ThisTopText: string;
  begin
    P := TIOParams.Create;
    try
      if P.Read(aImageFile) then
      begin
        FrameCount := P.ImageCount;
        if FrameCount = 1 then
          ThisTopText := ExtractFileName(aImageFile)
        else if FrameCount > 1 then
          ThisTopText := ExtractFileName(aImageFile) + ' (' + IntToStr(FrameCount) + ' frames)';

        ThisImage := mimgTest.AppendImage(aImageFile);
        mimgTest.ImageTopText[ThisImage] := ThisTopText;
        mimgTest.ImageInfoText[ThisImage] := IntToStr(mimgTest.ImageWidth[ThisImage]) + ' x ' + IntToStr(mimgTest.ImageHeight[ThisImage]);
        FImagePaths.Add(aImageFile);
      end;
    finally
      P.Free;
    end;
  end;

begin
  // ICO containing multiple frames:
  LoadLargestFrameFromIco('C:\DELPHI\_test\MIOLoadFirstFrame\TestIcon1.ico');

  // GIF:
  LoadImage('C:\DELPHI\_test\MIOLoadFirstFrame\TestGIF1.gif');

  // TIF:
  LoadImage('C:\DELPHI\_test\MIOLoadFirstFrame\TestTIFMulti.tif');

  // PNG:
  LoadImage('C:\DELPHI\_test\MIOLoadFirstFrame\flowers.png');

  // ICO containing only 1 frame:
  LoadLargestFrameFromIco('C:\DELPHI\_test\MIOLoadFirstFrame\Testicon2.ico');

  mimgTest.SelectedImage := 0;
  ShowFilePathInStatusBar(0);
end;




Here is the whole project, so you can test it in Delphi:

attach/PeterPanino/2021527165118_MIOLoadFirstFrame_v3.zip
737.9 KB
PeterPanino Posted - May 26 2021 : 08:42:53
To retrieve the number of the largest frame from the ICO file, I wrote this code:


P := TIOParams.Create;
if P.Read('TestIcon1.ico') then
begin
  LargestFrame := 0;
  LargestFrameIndex := 0;
  for i := 0 to P.ImageCount - 1 do
  begin
    WxH := P.ICO_Sizes[i].Width * P.ICO_Sizes[i].Height;
    if WxH > LargestFrame then
    begin
      LargestFrame := WxH;
      LargestFrameIndex := i;
    end;
  end;
  CodeSite.Send('LargestFrameIndex', LargestFrameIndex);
end;
P.Free;
PeterPanino Posted - May 26 2021 : 04:24:54
I have written this code to achieve this:

procedure TForm1.LoadMultiFrameFiles;
var
  B: TIEBitmap;
begin
  B := TIEBitmap.Create;
  try
    B.Read('C:\DELPHI\_test\MIOLoadFirstFrame\TestIcon1.ico');
    mimgTest.AppendImage(B);
    B.Read('C:\DELPHI\_test\MIOLoadFirstFrame\TestGIF1.gif');
    mimgTest.AppendImage(B);
    B.Read('C:\DELPHI\_test\MIOLoadFirstFrame\TestTIFMulti.tif');
    mimgTest.AppendImage(B);
  finally
    B.Free;
  end;
end;




Can this be optimized?

For example, in an .ICO file, how can I load the frame with the highest dimensions?

(TestIcon1.ico contains 8 frames where the first frame has the highest dimension, as you can see from this screenshot of another IconEditor app):



But despite the first frame is 128*128, it is displayed with poor quality in the ImageEnMView.

attach/PeterPanino/20215264381_TestIcon1.zip
13.05 KB