作者:匿名
发布:3/26/2025 1:25:44 PM

.NET Core图片处理库

图像格式和操作系统支持

所有库都支持广泛的图像类型。它们甚至支持最新的图像格式,如 Avif 和 Webp。不过 Skiasharp 目前不支持 Avif。Imagesharp 支持 Avif,但您需要安装不同的库来处理它。

Avif 是一种较新的图像格式,它可以将 JPEG 文件的文件大小减少 50%,与 Webp 相比减少 20%。Webp 在更多浏览器中得到了更好的支持。

获胜者:NetVips、ImageMagick

格式 Imagesharp Skiasharp Magick Netvips
Gif
Jpeg
Webp
Avif ✅*1,*2  
* 1仅限于较新版本
* 2仅通过安装另一个 nuget 包

支持的图像格式的完整列表:

对于网络图片我们应该使用什么格式?

WebP 浏览器支持:最新的 Chrome、Firefox、Safari 和 Edge 版本支持 WebP。这些是最常用的浏览器。IE 11 及更低版本不支持 WebP。如果出于某种原因您仍需要支持这些浏览器。Webp 不适合您。浏览器支持的完整列表:https://caniuse.com/webp

WebP 图像质量: Webp 和灰度渐变:https://eng.aurelienpierre.com/2021/10/webp-is-so-great-except-its-not/

除非您需要高图像保真度,否则建议使用 Webp。

Avif 浏览器支持:Avif 支持多种浏览器,支持最新版本的 Chrome、Firefox 和 Safari。Webp 对 Safari 的支持更好,支持较旧的 Safari 版本。不支持 IE10 和 11。兼容浏览器的完整列表:https://caniuse.com/avif

便于使用

ImageSharp 和 ImageMagick 都具有非常直观的 API。只需几行代码就可以调整图像大小并进行转换。SKiaSharp 需要更多代码,编写起来也更复杂。

ImageSharp 是用托管代码编写的,因此当应用程序部署到另一个操作系统时不需要额外的库。如果我们想将它部署到另一个操作系统,我们需要为其他库添加一个额外的包。

获胜者:ImageSharp

💵成本

所有图像库都是开源的。ImageSharp 需要付费许可才能用于商业用途。这使得 ImageSharp 成为商业项目的昂贵选择。

获胜者:SkiaSharp、Magick.net

🚀 性能

这些图像库在性能方面如何相互比较?在这里,我们将 2500x1500 大小的图像调整为 200x200,并将 jpeg 保存为 PNG。在这里,我们拉伸图像,但不进行任何高级调整大小,例如裁剪或填充。

这些是用于库的版本:

  • ImageSharp:v3.1.1
  • SkiaSharp:2.88
  • NetVips:2.4
  • Magic.Net 13.5
方法 输入扩展 输出扩展 平均值 误差 Gen0 Gen1 Gen2 已分配
ResizeWithImageSharp gif avif 162.83毫秒 NA 1000.0000 1000.0000 1000.0000 268.55 KB
ResizeWithMagick gif avif 283.19毫秒 NA - - - 32.18 KB
ResizeWithNetVips gif avif 181.84毫秒 NA - - - 4.27 KB
ResizeWithSkiaSharp gif avif NA NA NA NA NA NA
ResizeWithImageSharp gif png 71.23毫秒 NA 1000.0000 1000.0000 1000.0000 215.77 KB
ResizeWithMagick gif png 196.04毫秒 NA - - - 32.18 KB
ResizeWithNetVips gif png 63.32毫秒 NA - - - 4.26 KB
ResizeWithSkiaSharp gif png 46.40毫秒 NA - - - 3.01 KB
ResizeWithImageSharp gif webp 200.32毫秒 NA 2000.0000 1000.0000 1000.0000 7396.95 KB
ResizeWithMagick gif webp 178.21毫秒 NA - - - 31.9 KB
ResizeWithNetVips gif webp 68.57毫秒 NA - - - 4.27 KB
ResizeWithSkiaSharp gif webp 31.25毫秒 NA - - - 3.01 KB
ResizeWithImageSharp jpeg avif 235.00毫秒 NA - - - 540.24 KB  
ResizeWithMagick jpeg avif 229.63毫秒 NA - - - 31.91 KB
ResizeWithNetVips jpeg avif 156.38毫秒 NA - - - 4.28 KB
ResizeWithSkiaSharp jpeg avif NA NA NA NA NA NA
ResizeWithImageSharp jpeg png 145.29毫秒 NA - - - 456.34 KB
ResizeWithMagick jpeg png 184.33毫秒 NA - - - 32.18 KB
ResizeWithNetVips jpeg png 43.37毫秒 NA - - - 4.27 KB
ResizeWithSkiaSharp jpeg png 57.41毫秒 NA - - - 3.01 KB
ResizeWithImageSharp jpeg webp 162.81毫秒 NA - - - 4016.68 KB
ResizeWithMagick jpeg webp 152.31毫秒 NA - - - 31.91 KB
ResizeWithNetVips jpeg webp 45.96毫秒 NA - - - 4.28 KB
ResizeWithSkiaSharp jpeg webp 33.88毫秒 NA - - - 3.01 KB
ResizeWithImageSharp png avif 217.57毫秒 NA - - - 565.36 KB
ResizeWithMagick png avif 276.84毫秒 NA - - - 31.9 KB
ResizeWithNetVips png avif 192.78毫秒 NA - - - 4.27 KB
ResizeWithSkiaSharp png avif NA NA NA NA NA NA
ResizeWithImageSharp png png 146.53毫秒 NA - - - 513.58 KB
ResizeWithMagick png png 225.02毫秒 NA - - - 31.62 KB
ResizeWithNetVips png png 82.90毫秒 NA - - - 4.26 KB
ResizeWithSkiaSharp png png 87.49毫秒 NA - - - 2.73 KB
ResizeWithImageSharp png webp 321.22毫秒 NA 2000.0000 1000.0000 1000.0000 7658.14 KB
ResizeWithMagick png webp 205.96毫秒 NA - - - 31.9 KB
ResizeWithNetVips png webp 84.98毫秒 NA - - - 4.27 KB
ResizeWithSkiaSharp png webp 63.81毫秒 NA - - - 3.01 KB

这里我们可以看到 SkiaSharp 占用的内存更少,速度更快。ImageSharp、NetVips 和 SkiaSharp 之间的差异很小。性能也会因输出格式而异。

调整图像大小

获胜者: SkiaSharp

基准

在这个基准测试中,我们使用了一个简单的拉伸调整大小算法。这对于

       [MemoryDiagnoser]
    public class ImageResizeBenchmark
    {
        [Params("jpeg", "png", "gif")]
        public string InputExtension { get; set; } = String.Empty;

        [Params("png", "webp", "avif")]
        public string OutputExtension { get; set; } = String.Empty;

        const int Width = 331;
        const int Height = 200;

        [Benchmark]
        public void ResizeWithImageSharp()
        {
            using var stream = GetStream();
            using var image = SixLabors.ImageSharp.Image.Load(stream);

            int width = Width;
            int height = Height;
            image.Mutate(x => x.Resize(width, height));

            var encoder = OutputExtension switch
            {
                "png" => (IImageEncoder)new PngEncoder(),
                "webp" => (IImageEncoder)new WebpEncoder(),
                "avif" => (IImageEncoder)new AVIFEncoder(),
            };

            using var outputStream = GetOutputStream("imagesharp");
            image.Save(outputStream, encoder);

            outputStream.Close();
            stream.Close();
        }

        [Benchmark]
        public void ResizeWithMagick()
        {
            using var stream = GetStream();
            using var image = new MagickImage(stream);

            var size = new MagickGeometry(Width, Height)
            {
                IgnoreAspectRatio = true
            };
            var outputFormat = OutputExtension switch
            {
                "png" => MagickFormat.Png,
                "webp" => MagickFormat.WebP,
                "avif" => MagickFormat.Avif
            };
            image.Resize(size);
           
            // Save the result
            image.Write(GetOutputPath("magic"), outputFormat);
            stream.Close();
        }

        [Benchmark]
        public void ResizeWithNetVips()
        {
            string filename = $"images/input.{InputExtension}";
            var image = NetVips.Image.Thumbnail(filename, Width, Height,
                noRotate: false,
                crop: Enums.Interesting.All);

            var target = Target.NewToFile(GetOutputPath("netvips"));
            image.WriteToTarget(target, $".{OutputExtension}");
        }

        [Benchmark]
        public void ResizeWithSkiaSharp()
        {
            using var stream = GetStream();
            using var skData = SKData.Create(stream);
            using var codec = SKCodec.Create(skData);

            // boost performance by first getting an approximate size so we can decode the image directly in this dimension
            var supportedScale = codec
                 .GetScaledDimensions((float)Width / codec.Info.Width);

            var nearest = new SKImageInfo(supportedScale.Width, supportedScale.Height);
            using var destinationImage = SKBitmap.Decode(codec, nearest);
            using var resizedImage = destinationImage.Resize(new SKImageInfo(Width, Height), SKFilterQuality.High);

            var outputFormat = OutputExtension switch
            {
                "png" => SKEncodedImageFormat.Png,
                "webp" => SKEncodedImageFormat.Webp,
                "avif" => SKEncodedImageFormat.Avif
            };

            using var outputImage = SKImage.FromBitmap(resizedImage);
            using var data = outputImage.Encode(outputFormat, 90);
            using var outputStream = GetOutputStream("skiasharp");
            data.SaveTo(outputStream);
            
            outputStream.Close();
            stream.Close();
        }

        private FileStream GetOutputStream(string name)
            => File.Open(GetOutputPath(name), FileMode.Create);

        private FileStream GetStream()
            => File.OpenRead($"images/input.{InputExtension}");

        private string GetOutputPath(string name)
        {
            return $"/images/output_{name}_{InputExtension}_.{OutputExtension}";
        }
    }

结论

那么,哪个图像库最好用呢?答案是,视情况而定。ImageSharp 最适合开源项目,因为它免费且易于设置。它的性能比 SkiaSharp 或 NetVips 差,但差不了多少。

对于商业项目, Magick 和 SkiaSharp 更适合。

  Imagesharp SkiaSharp Magick NetVips
易于使用      
成本  
图像格式支持  
性能      
更新:2025-03-29
阅读:88
Posted by 1
0