Magick.NET
| Language | C# (.NET 10 and .NET Standard 2.0) |
|---|---|
| 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, all color types and bit depths, text chunks |
Magick.NET puts ImageMagick into a NuGet package: the native library is included for Windows, Linux and macOS, so there is nothing else to install. It reads and writes more than 100 formats, and its PNG support comes from libpng, so every PNG feature is available, including bit depth, color type, compression settings and text chunks.
There are 3 builds: Q8 (8 bits per channel, least memory), Q16 (16 bits, the default for most uses) and Q16-HDRI (floating point). Pick Q8 unless you process 16-bit PNG files. ImageOptimizer recompresses PNG files losslessly, which is useful for web assets.
Installation#
# 8 bits per channel, any CPU
dotnet add package Magick.NET-Q8-AnyCPU
# or 16 bits per channel
dotnet add package Magick.NET-Q16-AnyCPU
Basic usage: read, resize and save a PNG#
using ImageMagick;
using var image = new MagickImage("in.png");
Console.WriteLine($"{image.Width} x {image.Height}, {image.Depth}-bit {image.ColorType}");
image.Resize(400, 0); // 0 keeps the aspect ratio
image.Write("out.png");
How to get PNG width and height without decoding#
MagickImageInfo reads only the header (“ping” in ImageMagick terms):
using ImageMagick;
var info = new MagickImageInfo("in.png");
Console.WriteLine($"{info.Format}: {info.Width} x {info.Height}");
How to set PNG compression level and bit depth#
using ImageMagick;
using ImageMagick.Formats;
using var image = new MagickImage("in.png");
var defines = new PngWriteDefines
{
CompressionLevel = 9, // 0 .. 9
BitDepth = 8,
ColorType = ColorType.TrueColorAlpha,
ExcludeChunks = PngChunkFlags.All, // don't write metadata chunks
};
image.Write("out.png", defines);
How to optimize a PNG losslessly#
ImageOptimizer tries different filter and compression settings and keeps the smallest file. Pixels don’t change:
using ImageMagick;
var optimizer = new ImageOptimizer { OptimalCompression = true };
var file = new FileInfo("in.png");
long before = file.Length;
optimizer.LosslessCompress(file);
file.Refresh();
Console.WriteLine($"{before} -> {file.Length} bytes");
How to read PNG text chunks#
ImageMagick reads tEXt, zTXt and iTXt chunks as image attributes:
using ImageMagick;
using var image = new MagickImage("in.png");
foreach (string name in image.AttributeNames)
{
Console.WriteLine($"{name}: {image.GetAttribute(name)}");
}
image.SetAttribute("Software", "my app"); // written as a text chunk
image.Write("out.png");
How to convert PNG to JPEG or WebP#
using ImageMagick;
using var image = new MagickImage("in.png");
image.BackgroundColor = MagickColors.White;
image.Alpha(AlphaAction.Remove); // flatten transparency onto white
image.Quality = 85;
image.Write("out.jpg"); // format from the extension
image.Write("out.webp", MagickFormat.WebP);
Tips#
- Set
ResourceLimits.Width,ResourceLimits.HeightandResourceLimits.Memorybefore processing files from untrusted sources. MagickImageCollectionreads and writes multi-frame files (GIF, TIFF, ICO).- Width, height and sizes are
uintin Magick.NET 14 and later.