NetVips
| Language | C# (.NET Standard 2.0, .NET 6+) |
|---|---|
| License | MIT (libvips: LGPL-2.1) |
| Repository | github.com/kleisauke/net-vips |
| Documentation | NetVips documentation |
| Depends on | libvips (prebuilt in the NetVips.Native package), which uses libheif with libaom for AVIF |
| Read / write | yes / yes, 8/10/12-bit, alpha, animated AVIF |
NetVips wraps libvips, a demand-driven image processing library. It streams images in small pieces instead of loading them whole, so it’s fast and uses little memory, which makes it a good fit for web servers that make AVIF thumbnails. AVIF goes through libvips’ heifload and heifsave operations; saving to a .avif file selects AV1 compression.
The NetVips.Native package has prebuilt libvips binaries for Windows, Linux and macOS, built with libheif and libaom.
Installation#
Shell
dotnet add package NetVips
dotnet add package NetVips.Native
Basic usage: convert to AVIF and back#
C#
using NetVips;
using var image = Image.NewFromFile("photo.jpg");
Console.WriteLine($"{image.Width} x {image.Height}, {image.Bands} bands");
image.Heifsave("photo.avif", q: 60, compression: Enums.ForeignHeifCompression.Av1);
using var avif = Image.NewFromFile("photo.avif");
avif.WriteToFile("photo.png");
image.WriteToFile("photo.avif") also works: the .avif extension selects AV1.
How to make an AVIF thumbnail#
Thumbnail decodes only what it needs and resizes in one step:
C#
using var thumb = Image.Thumbnail("photo.jpg", 400); // 400 pixels wide
thumb.Heifsave("thumb.avif", q: 55, effort: 4, compression: Enums.ForeignHeifCompression.Av1);
How to set effort, bit depth and lossless mode#
C#
using var image = Image.NewFromFile("photo.png");
image.Heifsave("out.avif",
q: 60,
effort: 2, // 0 (fastest) .. 9 (slowest, smallest)
bitdepth: 10, // 8, 10 or 12
subsampleMode: Enums.ForeignSubsample.Off, // keep 4:4:4 chroma
compression: Enums.ForeignHeifCompression.Av1);
image.Heifsave("lossless.avif", lossless: true, compression: Enums.ForeignHeifCompression.Av1);
How to get AVIF width and height without decoding#
Opening an image only reads the header; pixels are decoded when you use them:
C#
using var image = Image.NewFromFile("photo.avif");
Console.WriteLine($"{image.Width} x {image.Height}, alpha: {image.HasAlpha()}");
How to encode AVIF to a byte array#
C#
using var image = Image.NewFromFile("photo.jpg");
byte[] avif = image.HeifsaveBuffer(q: 60, compression: Enums.ForeignHeifCompression.Av1);
Tips#
- Read all frames of an animated AVIF with
Image.NewFromFile("anim.avif", kwargs: new VOption { { "n", -1 } }); frames are stacked vertically, with the frame height in thepage-heightmetadata. - AVIF encoding is CPU-heavy: lower
effortfor interactive use, raise it for files you encode once and serve many times.