Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple class that converts a image to a icon in c# without losing image color data, unlike System.Drawing.Icon; ico with png data requires Windows Vista or above
class PngIconConverter
{
/* input image with width = height is suggested to get the best result */
/* png support in icon was introduced in Windows Vista */
public static bool Convert(System.IO.Stream input_stream, System.IO.Stream output_stream, int size, bool keep_aspect_ratio = false)
{
System.Drawing.Bitmap input_bit = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(input_stream);
if (input_bit != null)
{
int width, height;
if (keep_aspect_ratio)
{
width = size;
height = input_bit.Height / input_bit.Width * size;
}
else
{
width = height = size;
}
System.Drawing.Bitmap new_bit = new System.Drawing.Bitmap(input_bit, new System.Drawing.Size(width, height));
if (new_bit != null)
{
// save the resized png into a memory stream for future use
System.IO.MemoryStream mem_data = new System.IO.MemoryStream();
new_bit.Save(mem_data, System.Drawing.Imaging.ImageFormat.Png);
System.IO.BinaryWriter icon_writer = new System.IO.BinaryWriter(output_stream);
if (output_stream != null && icon_writer != null)
{
// 0-1 reserved, 0
icon_writer.Write((byte)0);
icon_writer.Write((byte)0);
// 2-3 image type, 1 = icon, 2 = cursor
icon_writer.Write((short)1);
// 4-5 number of images
icon_writer.Write((short)1);
// image entry 1
// 0 image width
icon_writer.Write((byte)width);
// 1 image height
icon_writer.Write((byte)height);
// 2 number of colors
icon_writer.Write((byte)0);
// 3 reserved
icon_writer.Write((byte)0);
// 4-5 color planes
icon_writer.Write((short)0);
// 6-7 bits per pixel
icon_writer.Write((short)32);
// 8-11 size of image data
icon_writer.Write((int)mem_data.Length);
// 12-15 offset of image data
icon_writer.Write((int)(6 + 16));
// write image data
// png data must contain the whole png data file
icon_writer.Write(mem_data.ToArray());
icon_writer.Flush();
return true;
}
}
return false;
}
return false;
}
public static bool Convert(string input_image, string output_icon, int size, bool keep_aspect_ratio = false)
{
System.IO.FileStream input_stream = new System.IO.FileStream(input_image, System.IO.FileMode.Open);
System.IO.FileStream output_stream = new System.IO.FileStream(output_icon, System.IO.FileMode.OpenOrCreate);
bool result = Convert(input_stream, output_stream, size, keep_aspect_ratio);
input_stream.Close();
output_stream.Close();
return result;
}
}
@kipusoep

This comment has been minimized.

Copy link

kipusoep commented Nov 6, 2014

Very nice, thanks!
I've added some documentation and renamed variables to comply with Microsoft standards:

/// <summary>
/// Provides helper methods for imaging
/// </summary>
public static class ImagingHelper
{
    /// <summary>
    /// Converts a PNG image to a icon (ico)
    /// </summary>
    /// <param name="input">The input stream</param>
    /// <param name="output">The output stream</param>
    /// <param name="size">The size (16x16 px by default)</param>
    /// <param name="preserveAspectRatio">Preserve the aspect ratio</param>
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(Stream input, Stream output, int size = 16, bool preserveAspectRatio = false)
    {
        Bitmap inputBitmap = (Bitmap)Bitmap.FromStream(input);
        if (inputBitmap != null)
        {
            int width, height;
            if (preserveAspectRatio)
            {
                width = size;
                height = inputBitmap.Height / inputBitmap.Width * size;
            }
            else
            {
                width = height = size;
            }
            Bitmap newBitmap = new Bitmap(inputBitmap, new Size(width, height));
            if (newBitmap != null)
            {
                // save the resized png into a memory stream for future use
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    newBitmap.Save(memoryStream, ImageFormat.Png);

                    BinaryWriter iconWriter = new BinaryWriter(output);
                    if (output != null && iconWriter != null)
                    {
                        // 0-1 reserved, 0
                        iconWriter.Write((byte)0);
                        iconWriter.Write((byte)0);

                        // 2-3 image type, 1 = icon, 2 = cursor
                        iconWriter.Write((short)1);

                        // 4-5 number of images
                        iconWriter.Write((short)1);

                        // image entry 1
                        // 0 image width
                        iconWriter.Write((byte)width);
                        // 1 image height
                        iconWriter.Write((byte)height);

                        // 2 number of colors
                        iconWriter.Write((byte)0);

                        // 3 reserved
                        iconWriter.Write((byte)0);

                        // 4-5 color planes
                        iconWriter.Write((short)0);

                        // 6-7 bits per pixel
                        iconWriter.Write((short)32);

                        // 8-11 size of image data
                        iconWriter.Write((int)memoryStream.Length);

                        // 12-15 offset of image data
                        iconWriter.Write((int)(6 + 16));

                        // write image data
                        // png data must contain the whole png data file
                        iconWriter.Write(memoryStream.ToArray());

                        iconWriter.Flush();

                        return true;
                    }
                }
            }
            return false;
        }
        return false;
    }

    /// <summary>
    /// Converts a PNG image to a icon (ico)
    /// </summary>
    /// <param name="inputPath">The input path</param>
    /// <param name="outputPath">The output path</param>
    /// <param name="size">The size (16x16 px by default)</param>
    /// <param name="preserveAspectRatio">Preserve the aspect ratio</param>
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(string inputPath, string outputPath, int size = 16, bool preserveAspectRatio = false)
    {
        using (FileStream inputStream = new FileStream(inputPath, FileMode.Open))
        using (FileStream outputStream = new FileStream(outputPath, FileMode.OpenOrCreate))
        {
            return ConvertToIcon(inputStream, outputStream, size, preserveAspectRatio);
        }
    }
}
@AbdlrhmanSheahta

This comment has been minimized.

Copy link

AbdlrhmanSheahta commented Oct 29, 2015

thank you very much dude , it's working well on converting , png to ico

@maurosampietro

This comment has been minimized.

Copy link

maurosampietro commented Mar 29, 2016

Fail fast, less indentation.

 public static class ImagingHelper
 {
        /// <summary>
        /// Converts a PNG image to a icon (ico)
        /// </summary>
        /// <param name="input">The input stream</param>
        /// <param name="output">The output stream</param>
        /// <param name="size">The size (16x16 px by default)</param>
        /// <param name="preserveAspectRatio">Preserve the aspect ratio</param>
        /// <returns>Wether or not the icon was succesfully generated</returns>
        public static bool ConvertToIcon( Stream input, Stream output, int size = 16, bool preserveAspectRatio = false )
        {
            var inputBitmap = (Bitmap)Bitmap.FromStream( input );
            if( inputBitmap == null )
                return false;

            int width = size, height = size;
            if( preserveAspectRatio )
            {
                width = size;
                height = inputBitmap.Height / inputBitmap.Width * size;
            }

            var newBitmap = new Bitmap( inputBitmap, new Size( width, height ) );
            if( newBitmap == null )
                return false;

            // save the resized png into a memory stream for future use
            using( MemoryStream memoryStream = new MemoryStream() )
            {
                newBitmap.Save( memoryStream, ImageFormat.Png );

                var iconWriter = new BinaryWriter( output );
                if( output == null || iconWriter == null )
                    return false;

                // 0-1 reserved, 0
                iconWriter.Write( (byte)0 );
                iconWriter.Write( (byte)0 );

                // 2-3 image type, 1 = icon, 2 = cursor
                iconWriter.Write( (short)1 );

                // 4-5 number of images
                iconWriter.Write( (short)1 );

                // image entry 1
                // 0 image width
                iconWriter.Write( (byte)width );
                // 1 image height
                iconWriter.Write( (byte)height );

                // 2 number of colors
                iconWriter.Write( (byte)0 );

                // 3 reserved
                iconWriter.Write( (byte)0 );

                // 4-5 color planes
                iconWriter.Write( (short)0 );

                // 6-7 bits per pixel
                iconWriter.Write( (short)32 );

                // 8-11 size of image data
                iconWriter.Write( (int)memoryStream.Length );

                // 12-15 offset of image data
                iconWriter.Write( (int)(6 + 16) );

                // write image data
                // png data must contain the whole png data file
                iconWriter.Write( memoryStream.ToArray() );

                iconWriter.Flush();
            }

            return true;
        }
 }
@DeepakkSHAW

This comment has been minimized.

Copy link

DeepakkSHAW commented Jul 22, 2016

Thanks.

@ratheeshalon

This comment has been minimized.

Copy link

ratheeshalon commented Nov 29, 2016

Thanks

@ChuckSavage

This comment has been minimized.

Copy link

ChuckSavage commented Jun 22, 2017

Preserve Aspect Ratio fixed.

Thanks so much for this code, it works amazing!

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

    /// <summary>
    /// Provides helper methods for imaging
    /// </summary>
    public static class IconHelper
    {
        /// <summary>
        /// Converts a PNG image to a icon (ico)
        /// </summary>
        /// <param name="input">The input stream</param>
        /// <param name="output">The output stream</param>
        /// <param name="size">Needs to be a factor of 2 (16x16 px by default)</param>
        /// <param name="preserveAspectRatio">Preserve the aspect ratio</param>
        /// <returns>Wether or not the icon was succesfully generated</returns>
        public static bool ConvertToIcon(Stream input, Stream output, int size = 16, bool preserveAspectRatio = false)
        {
            var inputBitmap = (Bitmap)Bitmap.FromStream(input);
            if (inputBitmap == null)
                return false;

            float width = size, height = size;
            if (preserveAspectRatio)
            {
                if (inputBitmap.Width > inputBitmap.Height)
                    height = ((float)inputBitmap.Height / inputBitmap.Width) * size;
                else
                    width = ((float)inputBitmap.Width / inputBitmap.Height) * size;
            }

            var newBitmap = new Bitmap(inputBitmap, new Size((int)width, (int)height));
            if (newBitmap == null)
                return false;

            // save the resized png into a memory stream for future use
            using (MemoryStream memoryStream = new MemoryStream())
            {
                newBitmap.Save(memoryStream, ImageFormat.Png);

                var iconWriter = new BinaryWriter(output);
                if (output == null || iconWriter == null)
                    return false;

                // 0-1 reserved, 0
                iconWriter.Write((byte)0);
                iconWriter.Write((byte)0);

                // 2-3 image type, 1 = icon, 2 = cursor
                iconWriter.Write((short)1);

                // 4-5 number of images
                iconWriter.Write((short)1);

                // image entry 1
                // 0 image width
                iconWriter.Write((byte)width);
                // 1 image height
                iconWriter.Write((byte)height);

                // 2 number of colors
                iconWriter.Write((byte)0);

                // 3 reserved
                iconWriter.Write((byte)0);

                // 4-5 color planes
                iconWriter.Write((short)0);

                // 6-7 bits per pixel
                iconWriter.Write((short)32);

                // 8-11 size of image data
                iconWriter.Write((int)memoryStream.Length);

                // 12-15 offset of image data
                iconWriter.Write((int)(6 + 16));

                // write image data
                // png data must contain the whole png data file
                iconWriter.Write(memoryStream.ToArray());

                iconWriter.Flush();
            }

            return true;
        }

        /// <summary>
        /// Converts a PNG image to a icon (ico)
        /// </summary>
        /// <param name="inputPath">The input path</param>
        /// <param name="outputPath">The output path</param>
        /// <param name="size">Needs to be a factor of 2 (16x16 px by default)</param>
        /// <param name="preserveAspectRatio">Preserve the aspect ratio</param>
        /// <returns>Wether or not the icon was succesfully generated</returns>
        public static bool ConvertToIcon(string inputPath, string outputPath, int size = 16, bool preserveAspectRatio = false)
        {
            using (FileStream inputStream = new FileStream(inputPath, FileMode.Open))
            using (FileStream outputStream = new FileStream(outputPath, FileMode.OpenOrCreate))
            {
                return ConvertToIcon(inputStream, outputStream, size, preserveAspectRatio);
            }
        }
    }

@youbodev

This comment has been minimized.

Copy link

youbodev commented Jul 16, 2017

thank you so much

@bananbl

This comment has been minimized.

Copy link

bananbl commented Aug 1, 2017

Thank you!
Wrapper added: converting Image object to Ico byte array.

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

/// <summary>
/// Provides helper methods for imaging
/// </summary>
public static class IconHelper
{
    /// <summary>
    /// Converts a PNG image to an icon (ico)
    /// </summary>
    /// <param name="input">The input stream</param>
    /// <param name="output">The output stream</param>
    /// <param name="size">Needs to be a factor of 2 (16x16 px by default)</param>
    /// <param name="preserveAspectRatio">Preserve the aspect ratio</param>
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(Stream input, Stream output, int size = 16, bool preserveAspectRatio = false)
    {
        var inputBitmap = (Bitmap)Bitmap.FromStream(input);
        if (inputBitmap == null)
            return false;

        float width = size, height = size;
        if (preserveAspectRatio)
        {
            if (inputBitmap.Width > inputBitmap.Height)
                height = ((float)inputBitmap.Height / inputBitmap.Width) * size;
            else
                width = ((float)inputBitmap.Width / inputBitmap.Height) * size;
        }

        var newBitmap = new Bitmap(inputBitmap, new Size((int)width, (int)height));
        if (newBitmap == null)
            return false;

        // save the resized png into a memory stream for future use
        using (MemoryStream memoryStream = new MemoryStream())
        {
            newBitmap.Save(memoryStream, ImageFormat.Png);

            var iconWriter = new BinaryWriter(output);
            if (output == null || iconWriter == null)
                return false;

            // 0-1 reserved, 0
            iconWriter.Write((byte)0);
            iconWriter.Write((byte)0);

            // 2-3 image type, 1 = icon, 2 = cursor
            iconWriter.Write((short)1);

            // 4-5 number of images
            iconWriter.Write((short)1);

            // image entry 1
            // 0 image width
            iconWriter.Write((byte)width);
            // 1 image height
            iconWriter.Write((byte)height);

            // 2 number of colors
            iconWriter.Write((byte)0);

            // 3 reserved
            iconWriter.Write((byte)0);

            // 4-5 color planes
            iconWriter.Write((short)0);

            // 6-7 bits per pixel
            iconWriter.Write((short)32);

            // 8-11 size of image data
            iconWriter.Write((int)memoryStream.Length);

            // 12-15 offset of image data
            iconWriter.Write((int)(6 + 16));

            // write image data
            // png data must contain the whole png data file
            iconWriter.Write(memoryStream.ToArray());

            iconWriter.Flush();
        }

        return true;
    }

    /// <summary>
    /// Converts a PNG image to an icon (ico)
    /// </summary>
    /// <param name="inputPath">The input path</param>
    /// <param name="outputPath">The output path</param>
    /// <param name="size">Needs to be a factor of 2 (16x16 px by default)</param>
    /// <param name="preserveAspectRatio">Preserve the aspect ratio</param>
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(string inputPath, string outputPath, int size = 16, bool preserveAspectRatio = false)
    {
        using (FileStream inputStream = new FileStream(inputPath, FileMode.Open))
        using (FileStream outputStream = new FileStream(outputPath, FileMode.OpenOrCreate))
        {
            return ConvertToIcon(inputStream, outputStream, size, preserveAspectRatio);
        }
    }

    /// <summary>
    /// Converts a PNG image to an icon (ico)
    /// </summary>
    /// <param name="inputPath">Image object</param>
    /// <param name="preserveAspectRatio">Preserve the aspect ratio</param>
    /// <returns>ico byte array / null for error</returns>
    public static byte[] ConvertToIcon(Image image, bool preserveAspectRatio = false)
    {
        MemoryStream inputStream = new MemoryStream();
        image.Save(inputStream, ImageFormat.Png);
        inputStream.Seek(0, SeekOrigin.Begin);
        MemoryStream outputStream = new MemoryStream();
        int size = image.Size.Width;
        if (!ConvertToIcon(inputStream, outputStream, size, preserveAspectRatio))
        {
            return null;
        }
        return outputStream.ToArray();
    }
}
@mdiller

This comment has been minimized.

Copy link

mdiller commented Mar 10, 2018

This was super useful to me. I modified it to create multiple images in one ico of varying sizes.

/// <summary>
/// Adapted from this gist: https://gist.github.com/darkfall/1656050
/// Provides helper methods for imaging
/// </summary>
public static class ImagingHelper
{
    /// <summary>
    /// Converts a PNG image to a icon (ico) with all the sizes windows likes
    /// </summary>
    /// <param name="inputBitmap">The input bitmap</param>
    /// <param name="output">The output stream</param>
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(Bitmap inputBitmap, Stream output)
    {
        if (inputBitmap == null)
            return false;

        int[] sizes = new int[] { 256, 48, 32, 16 };

        // Generate bitmaps for all the sizes and toss them in streams
        List<MemoryStream> imageStreams = new List<MemoryStream>();
        foreach (int size in sizes)
        {
            Bitmap newBitmap = ResizeImage(inputBitmap, size, size);
            if (newBitmap == null)
                return false;
            MemoryStream memoryStream = new MemoryStream();
            newBitmap.Save(memoryStream, ImageFormat.Png);
            imageStreams.Add(memoryStream);
        }

        BinaryWriter iconWriter = new BinaryWriter(output);
        if (output == null || iconWriter == null)
            return false;

        int offset = 0;

        // 0-1 reserved, 0
        iconWriter.Write((byte)0);
        iconWriter.Write((byte)0);

        // 2-3 image type, 1 = icon, 2 = cursor
        iconWriter.Write((short)1);

        // 4-5 number of images
        iconWriter.Write((short)sizes.Length);

        offset += 6 + (16 * sizes.Length);

        for (int i = 0; i < sizes.Length; i++)
        {
            // image entry 1
            // 0 image width
            iconWriter.Write((byte)sizes[i]);
            // 1 image height
            iconWriter.Write((byte)sizes[i]);

            // 2 number of colors
            iconWriter.Write((byte)0);

            // 3 reserved
            iconWriter.Write((byte)0);

            // 4-5 color planes
            iconWriter.Write((short)0);

            // 6-7 bits per pixel
            iconWriter.Write((short)32);

            // 8-11 size of image data
            iconWriter.Write((int)imageStreams[i].Length);

            // 12-15 offset of image data
            iconWriter.Write((int)offset);

            offset += (int)imageStreams[i].Length;
        }

        for (int i = 0; i < sizes.Length; i++)
        {
            // write image data
            // png data must contain the whole png data file
            iconWriter.Write(imageStreams[i].ToArray());
            imageStreams[i].Close();
        }

        iconWriter.Flush();

        return true;
    }

    /// <summary>
    /// Converts a PNG image to a icon (ico)
    /// </summary>
    /// <param name="input">The input stream</param>
    /// <param name="output">The output stream</param
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(Stream input, Stream output)
    {
        Bitmap inputBitmap = (Bitmap)Bitmap.FromStream(input);
        return ConvertToIcon(inputBitmap, output);
    }

    /// <summary>
    /// Converts a PNG image to a icon (ico)
    /// </summary>
    /// <param name="inputPath">The input path</param>
    /// <param name="outputPath">The output path</param>
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(string inputPath, string outputPath)
    {
        using (FileStream inputStream = new FileStream(inputPath, FileMode.Open))
        using (FileStream outputStream = new FileStream(outputPath, FileMode.OpenOrCreate))
        {
            return ConvertToIcon(inputStream, outputStream);
        }
    }



    /// <summary>
    /// Converts an image to a icon (ico)
    /// </summary>
    /// <param name="inputImage">The input image</param>
    /// <param name="outputPath">The output path</param>
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(Image inputImage, string outputPath)
    {
        using (FileStream outputStream = new FileStream(outputPath, FileMode.OpenOrCreate))
        {
            return ConvertToIcon(new Bitmap(inputImage), outputStream);
        }
    }


    /// <summary>
    /// Resize the image to the specified width and height.
    /// Found on stackoverflow: https://stackoverflow.com/questions/1922040/resize-an-image-c-sharp
    /// </summary>
    /// <param name="image">The image to resize.</param>
    /// <param name="width">The width to resize to.</param>
    /// <param name="height">The height to resize to.</param>
    /// <returns>The resized image.</returns>
    public static Bitmap ResizeImage(Image image, int width, int height)
    {
        var destRect = new Rectangle(0, 0, width, height);
        var destImage = new Bitmap(width, height);

        destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

        using (var graphics = Graphics.FromImage(destImage))
        {
            graphics.CompositingMode = CompositingMode.SourceCopy;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

            using (var wrapMode = new ImageAttributes())
            {
                wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
            }
        }

        return destImage;
    }
}
@prepare

This comment has been minimized.

Copy link

prepare commented May 20, 2019

Hello @darkfall, @mdiller
Could you provide a license for your source code?

@darkfall

This comment has been minimized.

Copy link
Owner Author

darkfall commented May 20, 2019

Hello @darkfall, @mdiller
Could you provide a license for your source code?

CC-BY-SA. Feel free to use it

@prepare

This comment has been minimized.

Copy link

prepare commented May 20, 2019

Thank you 👍

@mdiller

This comment has been minimized.

Copy link

mdiller commented May 20, 2019

Hello @darkfall, @mdiller
Could you provide a license for your source code?

As darkfall said, CC-BY-SA. Feel free to use my modifications!

@zzxxhhzxh

This comment has been minimized.

Copy link

zzxxhhzxh commented Aug 4, 2019

This was super useful to me. I modified it to create multiple images in one ico of varying sizes.

/// <summary>
/// Adapted from this gist: https://gist.github.com/darkfall/1656050
/// Provides helper methods for imaging
/// </summary>
public static class ImagingHelper
{
    /// <summary>
    /// Converts a PNG image to a icon (ico) with all the sizes windows likes
    /// </summary>
    /// <param name="inputBitmap">The input bitmap</param>
    /// <param name="output">The output stream</param>
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(Bitmap inputBitmap, Stream output)
    {
        if (inputBitmap == null)
            return false;

        int[] sizes = new int[] { 256, 48, 32, 16 };

        // Generate bitmaps for all the sizes and toss them in streams
        List<MemoryStream> imageStreams = new List<MemoryStream>();
        foreach (int size in sizes)
        {
            Bitmap newBitmap = ResizeImage(inputBitmap, size, size);
            if (newBitmap == null)
                return false;
            MemoryStream memoryStream = new MemoryStream();
            newBitmap.Save(memoryStream, ImageFormat.Png);
            imageStreams.Add(memoryStream);
        }

        BinaryWriter iconWriter = new BinaryWriter(output);
        if (output == null || iconWriter == null)
            return false;

        int offset = 0;

        // 0-1 reserved, 0
        iconWriter.Write((byte)0);
        iconWriter.Write((byte)0);

        // 2-3 image type, 1 = icon, 2 = cursor
        iconWriter.Write((short)1);

        // 4-5 number of images
        iconWriter.Write((short)sizes.Length);

        offset += 6 + (16 * sizes.Length);

        for (int i = 0; i < sizes.Length; i++)
        {
            // image entry 1
            // 0 image width
            iconWriter.Write((byte)sizes[i]);
            // 1 image height
            iconWriter.Write((byte)sizes[i]);

            // 2 number of colors
            iconWriter.Write((byte)0);

            // 3 reserved
            iconWriter.Write((byte)0);

            // 4-5 color planes
            iconWriter.Write((short)0);

            // 6-7 bits per pixel
            iconWriter.Write((short)32);

            // 8-11 size of image data
            iconWriter.Write((int)imageStreams[i].Length);

            // 12-15 offset of image data
            iconWriter.Write((int)offset);

            offset += (int)imageStreams[i].Length;
        }

        for (int i = 0; i < sizes.Length; i++)
        {
            // write image data
            // png data must contain the whole png data file
            iconWriter.Write(imageStreams[i].ToArray());
            imageStreams[i].Close();
        }

        iconWriter.Flush();

        return true;
    }

    /// <summary>
    /// Converts a PNG image to a icon (ico)
    /// </summary>
    /// <param name="input">The input stream</param>
    /// <param name="output">The output stream</param
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(Stream input, Stream output)
    {
        Bitmap inputBitmap = (Bitmap)Bitmap.FromStream(input);
        return ConvertToIcon(inputBitmap, output);
    }

    /// <summary>
    /// Converts a PNG image to a icon (ico)
    /// </summary>
    /// <param name="inputPath">The input path</param>
    /// <param name="outputPath">The output path</param>
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(string inputPath, string outputPath)
    {
        using (FileStream inputStream = new FileStream(inputPath, FileMode.Open))
        using (FileStream outputStream = new FileStream(outputPath, FileMode.OpenOrCreate))
        {
            return ConvertToIcon(inputStream, outputStream);
        }
    }



    /// <summary>
    /// Converts an image to a icon (ico)
    /// </summary>
    /// <param name="inputImage">The input image</param>
    /// <param name="outputPath">The output path</param>
    /// <returns>Wether or not the icon was succesfully generated</returns>
    public static bool ConvertToIcon(Image inputImage, string outputPath)
    {
        using (FileStream outputStream = new FileStream(outputPath, FileMode.OpenOrCreate))
        {
            return ConvertToIcon(new Bitmap(inputImage), outputStream);
        }
    }


    /// <summary>
    /// Resize the image to the specified width and height.
    /// Found on stackoverflow: https://stackoverflow.com/questions/1922040/resize-an-image-c-sharp
    /// </summary>
    /// <param name="image">The image to resize.</param>
    /// <param name="width">The width to resize to.</param>
    /// <param name="height">The height to resize to.</param>
    /// <returns>The resized image.</returns>
    public static Bitmap ResizeImage(Image image, int width, int height)
    {
        var destRect = new Rectangle(0, 0, width, height);
        var destImage = new Bitmap(width, height);

        destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

        using (var graphics = Graphics.FromImage(destImage))
        {
            graphics.CompositingMode = CompositingMode.SourceCopy;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

            using (var wrapMode = new ImageAttributes())
            {
                wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
            }
        }

        return destImage;
    }
}

I use your code to create a icon including some sizes like 3232, 4848, 256*256. But if I use var bmp = (Bitmap)Image.FromFile(iconFilePath).Clone(), it failed, shows"GDI+ error". So how to open the icon file correctly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.