Ejemplo n.º 1
0
        /// <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();
            }
        }