Skip to content

Instantly share code, notes, and snippets.

@darkfall
Created January 22, 2012 07:15
Show Gist options
  • Save darkfall/1656050 to your computer and use it in GitHub Desktop.
Save darkfall/1656050 to your computer and use it in GitHub Desktop.
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;
}
}
@mdiller
Copy link

mdiller commented Apr 22, 2021

Sure!

@sakul-the-one
Copy link

sakul-the-one commented Apr 23, 2021

great, thx, here is btw the respondity for the DLL: CSBeginnerHelp

@tkefauver
Copy link

Thanks for this!

If you get EndOfStreamException when using the Stream output do this before using it:
output.Position = 0;

@cktgh
Copy link

cktgh commented Feb 21, 2024

Unfortunately this cannot be used on Powershell Core, System.Drawing.Bitmap is not available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment