• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 699
  • Last Modified:

How to extract the proper sized icon from .ico file

I am getting .ico files from our UX dept.  Each has the same image drawn to three different scales; 16x16, 24x24 and 32x32.  My screens need to be able to extract the icon of the correct size to use dynamically, as the sizes needed can change quickly.

Image image = GetImageFile("imagename");
Image image16 = ???

Assuming that image is an .ICO file with three image sizes, and given that I know I want the 16x16 size, how would I extract the proper Image?
0
FrancineTaylor
Asked:
FrancineTaylor
  • 4
  • 4
1 Solution
 
wdosanjosCommented:
It would be something like this:

Icon image = new Icon("imagename");
Icon image16 = new Icon(image, new Size(16, 16));

More about Icon here:
http://msdn.microsoft.com/en-us/library/system.drawing.icon.aspx
0
 
FrancineTaylorAuthor Commented:
Nope, didn't work.  I need to end up with an Bitmap, since it will be loaded into an ImageList, so I adapted the above code as follows:

                // bmp is the image I start out with
                IntPtr Hicon = bmp.GetHicon();
                Icon newIcon = Icon.FromHandle(Hicon);
                Icon icon16 = new Icon(newIcon, new Size(16, 16));

                rect = new Rectangle(new Point(10, 200), new Size(16, 16));
                g.DrawImage(icon16.ToBitmap(), rect);

The image which was drawn was the 32x32 image resized, not the 16x16.  I don't want to resize the image, I want to extract the correct one from the .ico file.

0
 
wdosanjosCommented:
I think by the time you get the icon on bmp it is already the 32x32 version and you no longer have access to the 16x16 version.

Can you show the code that loads the icon into bmp?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
FrancineTaylorAuthor Commented:
The .bmps are obtained through the following method:

public static List<Image> CreateIconList(string fileName) {
    IDictionaryEnumerator dictEnum = null;
    List<Image> images = new List<Image>();
    string iconName = null;
    using (ResourceReader reader = GetResourceReader(fileName)) {
        dictEnum = reader.GetEnumerator();

        while (dictEnum.MoveNext()) {
             iconName = dictEnum.Key.ToString().ToUpper().Substring(0, dictEnum.Key.ToString().LastIndexOf("."));
             images.Add(ValueToImage(dictEnum.Value));
        }
    }
    return images;
}

// translates a ResourceReader enumerator value object into an Image
public static Image ValueToImage(object value) {
    ImageConverter imageConverterObject = new ImageConverter();
    Image image = null;
    try {
        if (value.GetType().Equals(typeof(Bitmap))) {
            Bitmap bitmap = value as System.Drawing.Bitmap;
            image = (Image)bitmap;
        }
        else {
            image = (Image)imageConverterObject.ConvertFrom(value);
        }
    }
    catch (Exception ex) {
        throw (new Exception("Cannot convert image of type: " + value.GetType()));
    }
    return image;
}
public static ResourceReader GetResourceReader(string fileName) {
    ResourceReader reader = new ResourceReader(fileName);
    return reader;
}
0
 
wdosanjosCommented:
If your icons are .ico files stored in the resources file, they are already of type Icon and there is no need to perform a conversion. The code should look like something like this:

public static List<Icon> CreateIconList(string fileName) {
    IDictionaryEnumerator dictEnum = null;
    List<Icon> images = new List<Icon>();
    string iconName = null;
    using (ResourceReader reader = GetResourceReader(fileName)) {
        dictEnum = reader.GetEnumerator();

        while (dictEnum.MoveNext()) {
             iconName = dictEnum.Key.ToString().ToUpper().Substring(0, dictEnum.Key.ToString().LastIndexOf("."));
             images.Add((Icon)dictEnum.Value);
        }
    }
    return images;
}

public static ResourceReader GetResourceReader(string fileName) {
    ResourceReader reader = new ResourceReader(fileName);
    return reader;
}

Open in new window


I hope this helps.
0
 
FrancineTaylorAuthor Commented:
Yes, this is pretty much a duplicate of the code we have been using in our application.  Everyone assumed that it was giving us what we wanted, although the User Experience team would occasionally complain that the icons embedded in the treeview looked "fuzzy".

Then I got myself an icon containing four different sized images, each visually distinct so I could tell which one I was working with, embedded it in the .resource file and used it.  Turns out that when we get the icon out of the .resource file, it only has one of the images in it, the size 32x32, so all the 16x16 images were just 32x32 downsized, which was why they were fuzzy.

The above code works fine with single image files, but not with multi-image icons.
0
 
wdosanjosCommented:
The code above retrieves the icons with all available images in them.  To only retrieve the 16x16 images, you would do something like this:

Line 10:             images.Add(new Icon((Icon)dictEnum.Value, 16, 16));

What that does is to create a new Icon object from the 16x16 image in the .ico file (if one exists).  You can inspect the Icon.Size property to verify the size of the icon instance.   If no 16x16 version exists, it will use the image with the closest size.

I hope this helps.
0
 
FrancineTaylorAuthor Commented:
Well, I'll be danged.  It works!  Thanks for your patience and expertise, wdosanjos...
0

Featured Post

NEW Veeam Backup for Microsoft Office 365 1.5

With Office 365, it’s your data and your responsibility to protect it. NEW Veeam Backup for Microsoft Office 365 eliminates the risk of losing access to your Office 365 data.

  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now