/// <summary> /// Write the images to the stream as icon /// Every image is resized to 256x256 (but the content maintains the aspect ratio) /// </summary> /// <param name="stream">Stream to write to</param> /// <param name="images">List of images</param> public static void WriteIcon(Stream stream, IList <Image> images) { var binaryWriter = new BinaryWriter(stream); // // ICONDIR structure // binaryWriter.Write((short)0); // reserved binaryWriter.Write((short)1); // image type (icon) binaryWriter.Write((short)images.Count); // number of images IList <Size> imageSizes = new List <Size>(); IList <MemoryStream> encodedImages = new List <MemoryStream>(); foreach (var image in images) { // Pick the best fit var sizes = new[] { 16, 32, 48 }; int size = 256; foreach (var possibleSize in sizes) { if (image.Width <= possibleSize && image.Height <= possibleSize) { size = possibleSize; break; } } var imageStream = new MemoryStream(); if (image.Width == size && image.Height == size) { using (var clonedImage = ImageHelper.Clone(image, PixelFormat.Format32bppArgb)) { clonedImage.Save(imageStream, ImageFormat.Png); imageSizes.Add(new Size(size, size)); } } else { // Resize to the specified size, first make sure the image is 32bpp using (var clonedImage = ImageHelper.Clone(image, PixelFormat.Format32bppArgb)) { using (var resizedImage = ImageHelper.ResizeImage(clonedImage, true, true, Color.Empty, size, size, null)) { resizedImage.Save(imageStream, ImageFormat.Png); imageSizes.Add(resizedImage.Size); } } } imageStream.Seek(0, SeekOrigin.Begin); encodedImages.Add(imageStream); } // // ICONDIRENTRY structure // const int iconDirSize = 6; const int iconDirEntrySize = 16; var offset = iconDirSize + (images.Count * iconDirEntrySize); for (int i = 0; i < images.Count; i++) { var imageSize = imageSizes[i]; // Write the width / height, 0 means 256 binaryWriter.Write(imageSize.Width == 256 ? (byte)0 : (byte)imageSize.Width); binaryWriter.Write(imageSize.Height == 256 ? (byte)0 : (byte)imageSize.Height); binaryWriter.Write((byte)0); // no pallete binaryWriter.Write((byte)0); // reserved binaryWriter.Write((short)0); // no color planes binaryWriter.Write((short)32); // 32 bpp binaryWriter.Write((int)encodedImages[i].Length); // image data length binaryWriter.Write(offset); offset += (int)encodedImages[i].Length; } binaryWriter.Flush(); // // Write image data // foreach (var encodedImage in encodedImages) { encodedImage.WriteTo(stream); encodedImage.Dispose(); } }