Magick.NET
| Language | C# (.NET 8 and later, .NET Standard 2.0, .NET Framework 4.7) |
|---|---|
| License | Apache 2.0 (ImageMagick license for the native part) |
| Repository | github.com/dlemstra/Magick.NET |
| Documentation | docs in the repository |
| Depends on | native ImageMagick (bundled in the NuGet package) |
| Read / write | yes / yes, every entry, BMP and PNG entries; CUR read |
Magick.NET is ImageMagick for .NET. Its ICO support comes from ImageMagick’s icon coder: reading gives one image per icon entry in a MagickImageCollection, and writing a collection produces one entry per image. Entries are stored as BMP unless they are larger than 256x256 or you set the PNG size threshold.
It runs on Windows, Linux and macOS, so it’s a good choice for generating icons and favicons on a build server. It doesn’t expose cursor hotspots.
Installation#
dotnet add package Magick.NET-Q8-AnyCPU
Q8 (8 bits per channel) is enough for icons.
Basic usage: list the entries of an ICO file#
using ImageMagick;
using var entries = new MagickImageCollection("app.ico");
for (int i = 0; i < entries.Count; i++)
{
var img = entries[i];
Console.WriteLine($"{i}: {img.Width} x {img.Height}, {img.Depth}-bit, alpha: {img.HasAlpha}");
}
How to get icon sizes without decoding pixels#
using ImageMagick;
foreach (var info in MagickImageInfo.ReadCollection("app.ico"))
Console.WriteLine($"{info.Width} x {info.Height}");
How to convert ICO to PNG#
Save the largest entry:
using ImageMagick;
using var entries = new MagickImageCollection("app.ico");
var largest = entries.OrderByDescending(e => e.Width * e.Height).First();
largest.Write("app.png", MagickFormat.Png);
How to create a multi-size favicon.ico#
The icon:auto-resize define resizes one image to every listed size when it’s written as ICO. PngCompressionSize = 256 stores the 256x256 entry as PNG:
using ImageMagick;
using ImageMagick.Formats;
using var logo = new MagickImage("logo.png");
logo.Settings.SetDefine(MagickFormat.Icon, "auto-resize", "256,64,48,32,16");
logo.Settings.SetDefines(new IconWriteDefines { PngCompressionSize = 256 });
logo.Write("favicon.ico", MagickFormat.Icon);
Pass the list of sizes as a string: IconWriteDefines.AutoResize = true writes the value true, which ImageMagick doesn’t accept as a size list.
How to build an ICO from separate images#
When you have hand-drawn small sizes, add them to a collection and write it:
using ImageMagick;
using var icon = new MagickImageCollection();
foreach (var file in new[] { "icon16.png", "icon32.png", "icon48.png", "icon256.png" })
icon.Add(new MagickImage(file));
icon.Write("app.ico", MagickFormat.Icon);
Tips#
- Use
MagickFormat.IcoorMagickFormat.Iconwhen the file name has no.icoextension, e.g. when writing to a stream. - ImageMagick rejects images larger than 512x512 when writing ICO; keep entries at 256x256 or smaller for Windows.