Based on your criteria, this may not be possible because icons often and usually have more than 1 icon with the same width such as 16x16 4-bit, 16x16 8-bit, 16x16 24-bit and 16x16, 32-bit. As such, it is impossible to get the smallest icon based on the minimum width because in this case there are 4 icons, all with the same dimensions.
Even if you searched the icon for 16x16 24-bit frames there still can be more than one icon frame with a width of 16 and a bit depth of 24.
So I suppose at best, you need to search not only for the minimum size, but a specific bit depth as well. Even then the search may be incorrect if there are more than one frame with the same width and bit depth.
To get you started here is some code:
procedure TForm1.Open1Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
begin
if FileExists(OpenPictureDialog1.FileName) then
ImageEnIO1.LoadFromFile(OpenPictureDialog1.FileName);
end;
end;
procedure TForm1.SaveSmallestFrame1Click(Sender: TObject);
var
i: integer;
iFrames: integer;
iWidth1: integer;
iWidth2: integer;
iSmallestIndex: integer;
iSmallestWidth: integer;
iBitDepth: integer;
begin
if SavePictureDialog1.Execute then
begin
iSmallestIndex := -1;
if FileExists(OpenPictureDialog1.FileName) then
begin
ImageEnIO1.LoadFromFile(SavePictureDialog1.FileName);
iFrames := ImageEnIO1.Params.ImageCount;
for i := 0 to iFrames - 1 do
begin
ImageEnIO1.Params.ImageIndex := i;
iWidth1 := ImageEnIO1.Params.Width;
iBitDepth := ImageEnIO1.Params.BitsPerSample * ImageEnIO1.Params.SamplesPerPixel;
{ Search only for 24-Bit icons }
if iBitDepth <> 24 then
break;
ImageEnIO1.Params.ImageIndex := i + 1;
iWidth2 := ImageEnIO1.Params.Width;
iSmallestWidth := Min(iWidth1, iWidth2);
if iWidth1 = iSmallestWidth then
iSmallestIndex := i;
end;
if iSmallestIndex <> -1 then
begin
ImageEnIO1.Params.ImageIndex := iSmallestIndex;
ImageEnIO1.SaveToFile(OpenPictureDialog1.FileName);
end;
end;
end;
I have not taken the time to test this, but it will get you started.
Nigel may also have some ideas to accomplish this.
Another much simpler and more reliable way would be to load the icons into a TImageEnMView, set EnableMultipleSelect property to true then select the frame you want to save and call this:
procedure TForm1.Open1Click(Sender: TObject);
{ Open the image. }
var
i: Integer;
begin
OpenPictureDialog1.DefaultExt := 'png';
OpenPictureDialog1.Filename := ExtractFileName(AFilename);
if OpenPictureDialog1.Execute then
begin
if FileExists(OpenPictureDialog1.Filename) then
begin
AFilename := OpenPictureDialog1.Filename;
ImageEnMView1.MIO.LoadFromFile(AFilename, False);
if ImageEnMView1.MIO.Aborting then
begin
MessageBox(0, 'An error occurred opening the file.', 'Error', MB_ICONERROR or MB_OK);
exit;
end;
ImageEnMView1.SelectedImage := 0;
{ Set the frame to load }
ImageEnView1.IO.Params.ImageIndex := ImageEnMView1.SelectedImage;
{ Load the frame }
ImageEnView1.IEBitmap.AssignImage(ImageEnMView1.GetTIEBitmap(ImageEnMView1.SelectedImage));
ImageEnView1.Update;
ImageEnView1.IEBitmap.Modified := False;
for i := 0 to ImageEnMView1.ImageCount - 1 do
begin
ImageEnMView1.ImageBottomText[i] := 'Frame ' + IntToStr(i + 1);
if ImageEnMView1.MIO.Params[i].FileType = ioICO then
begin
case ImageEnMView1.MIO.Params[i].ICO_BitCount[i] of
32:
begin
ImageEnMView1.MIO.Params[i].BitsPerSample := 8;
ImageEnMView1.MIO.Params[i].SamplesPerPixel := 4;
end;
24:
begin
ImageEnMView1.MIO.Params[i].BitsPerSample := 8;
ImageEnMView1.MIO.Params[i].SamplesPerPixel := 3;
end;
8:
begin
ImageEnMView1.MIO.Params[i].BitsPerSample := 8;
ImageEnMView1.MIO.Params[i].SamplesPerPixel := 1;
end;
4:
begin
ImageEnMView1.MIO.Params[i].BitsPerSample := 4;
ImageEnMView1.MIO.Params[i].SamplesPerPixel := 1;
end;
end; // case
end;
end;
if ImageEnView1.IO.Params.BitsPerSample * ImageEnView1.IO.Params.SamplesPerPixel = 32 then
begin
{ If the bitdepth is 32 then display with a chessboard style }
ImageEnView1.Background := clBtnFace;
ImageEnView1.BackgroundStyle := iebsChessboard;
ImageEnView1.SetChessboardStyle(8);
ImageEnView1.Update;
end;
ImageEnView1.Fit;
end;
end;
end;
procedure TForm1.SaveAs1Click(Sender: TObject);
{ Save the image with a new filename. }
begin
SavePictureDialog1.DefaultExt := 'ico';
SavePictureDialog1.Filename := JustName(AFilename);
if SavePictureDialog1.Execute then
begin
Screen.Cursor := crHourGlass;
try
AFilename := SavePictureDialog1.Filename;
{ Save only selected frame }
ImageEnMView1.MIO.SaveToFile(AFilename, True);
if ImageEnMView1.MIO.Aborting then
begin
MessageBox(0, 'An error occurred saveing the file.', 'Error', MB_ICONERROR or MB_OK);
exit;
end;
ImageEnView1.IEBitmap.Modified := False;
finally
Screen.Cursor := crDefault;
end;
end;
end;
Bill Miller
Adirondack Software & Graphics
Email: w2m@hughes.net
EBook: http://www.imageen.com/ebook/
Custom Commercial ImageEn Development