返回

.NET 跨平台图像处理库 SixLabors.ImageSharp 特性、安装与使用示例

2025-10-16 .NET 跨平台 ImageSharp 388 0

在 .NET 生态中,传统的 System.Drawing 库在跨平台支持、性能、内存管理等方面有不少限制。为此,SixLabors 团队推出了 ImageSharp —— 一个完全托管 (managed)、跨平台、面向 .NET Core/.NET 6+ 的现代图像处理库。它不依赖于操作系统本地图形组件,可以在 Windows、Linux、macOS 等平台上一致地处理图像。

本文将从设计理念、关键特性入手,然后展示安装与基本用法,进而深入几个进阶场景,帮助你系统地理解并掌握 ImageSharp 的使用。

ImageSharp 的定位与核心特性

  • 纯托管、跨平台:ImageSharp 完全用 C# 实现,无需依赖底层操作系统的 GDI+、libgdiplus 或其他本地库。这样的设计使它在多个平台上的行为一致,并且易于在服务器、云端环境使用。
  • 丰富的图像格式支持:ImageSharp 支持多种常见图像格式的读写,如 JPEG、PNG、GIF、BMP、TIFF、WebP、QOI 等。它可以根据输入文件自动识别格式,也可以在保存时显式指定编码器。
  • 多像素格式与颜色空间:支持多种像素格式(例如 Rgba32Rgb24Rgba64 等),并具备色彩空间转换(RGB、灰度、CMYK、CIELab 等)能力。它还支持图像元数据(EXIF、IPTC、XMP)读写。
  • 丰富的图像处理操作:内置超过 40 多种图像处理操作,如缩放 (resize)、裁剪 (crop)、旋转 (rotate)、翻转 (flip)、模糊 (blur)、锐化 (sharpen)、颜色调整 (brightness、contrast)、滤镜 (grayscale、sepia)、边缘检测 (edge detection)、混合 (blend) 等。
  • 高性能与内存优化:ImageSharp 设计时就考虑性能,它内部使用了内存池 (memory pooling)、缓存重用、延迟执行等策略,以减少垃圾回收开销。对于大尺寸图像的处理也能保持较好的性能表现。
  • 可扩展与模块化:ImageSharp 提供可扩展的 API,方便你自定义图像处理管道、编写自定义过滤器和变换操作。同时,它还提供子库(如 ImageSharp.Drawing)用于矢量绘制、文字渲染等场景扩展。

安装与入门

1. 安装包

使用 NuGet 安装:

dotnet add package SixLabors.ImageSharp

如果你还需要进行矢量绘制、文本、路径等扩展功能,则可能还要安装:

dotnet add package SixLabors.ImageSharp.Drawing

2. 基本引入

在 C# 文件中常用命名空间包括:

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;            // 核心变换操作
using SixLabors.ImageSharp.PixelFormats;           // 像素格式定义
using SixLabors.ImageSharp.Formats;                // 格式与编码器
// 如需绘制、文字、路径等,还可用:
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.Fonts;

3. 加载与保存图像

最基础的用法是从文件或流加载图像,进行处理,再保存回文件或流。

using (Image image = Image.Load("input.jpg"))
{
    image.Mutate(x => x.Resize(800, 600));
    image.Save("output.jpg");  // 自动使用 JPG 编码器
}

你也可以显式指定像素格式:

using (Image<Rgba32> image = Image.Load<Rgba32>("input.png"))
{
    image.Mutate(x => x.Resize(400, 0));  // 高度按比例自动计算
    image.Save("resized.png");
}

如果你希望在保存时指定编码器参数(如 JPEG 质量、WebP 压缩等级等):

var encoder = new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder
{
    Quality = 80
};
image.Save("output_quality80.jpg", encoder);

4. 查询图像信息

如果你只想获取图像的宽高、格式、元数据等,而不对整个图像进行解码,可以使用 Image.Identify:

ImageInfo info = Image.Identify("input.jpg");
Console.WriteLine($"宽:{info.Width}, 高:{info.Height}");
var meta = info.Metadata;  // 包含 EXIF、ICC、XMP 等(如果有)

这个方法在不解码像素的情况下更轻量快速。

常用图像处理操作

以下是一些典型的、常见的图像处理场景与示例代码。

1. 缩放 / 裁剪 / 裁边

using (Image<Rgba32> img = Image.Load<Rgba32>("input.jpg"))
{
    img.Mutate(x =>
    {
        x.Resize(600, 0);                      // 等比缩放,宽设为 600
        x.Crop(new Rectangle(0, 0, 600, 400)); // 裁剪到 600x400
    });
    img.Save("cropped.jpg");
}

2. 旋转 / 翻转 / 镜像操作

img.Mutate(x => 
    x.Rotate(90)     // 顺时针旋转 90 度
     .Flip(FlipMode.Horizontal)  // 水平翻转
);

3. 滤镜 / 调整颜色

img.Mutate(x =>
    x.Grayscale()                         // 灰度滤镜
     .Brightness(1.2f)                    // 提高亮度
     .Contrast(1.5f)                      // 调整对比度
     .GaussianBlur(2)                     // 高斯模糊
);

4. 绘制图形 / 文本 / 矢量路径(用 ImageSharp.Drawing)

如果你安装了 SixLabors.ImageSharp.Drawing,可以在图像上绘制路径、填充形状或添加文字:

using Image image = new Image<Rgba32>(400, 200);
image.Mutate(ctx =>
{
    // 填充背景
    ctx.Fill(Color.LightGray);

    // 绘制一个红色星形
    var star = new SixLabors.ImageSharp.Drawing.Star(100f, 100f, 5, 20, 40);
    ctx.Fill(Color.Red, star);

    // 绘制文字
    FontCollection fonts = new FontCollection();
    FontFamily family = fonts.Add("path/to/your/font.ttf");
    Font font = family.CreateFont(24, FontStyle.Bold);
    ctx.DrawText("Hello ImageSharp", font, Color.Black, new PointF(10, 160));
});
image.Save("drawn.png");

5. 逐像素处理(高效访问像素)

对于需要更精细控制的操作,比如替换颜色、按像素计算等,可以使用 ProcessPixelRows 方法:

using (Image<Rgba32> img = Image.Load<Rgba32>("input.png"))
{
    img.ProcessPixelRows(accessor =>
    {
        for (int y = 0; y < accessor.Height; y++)
        {
            Span<Rgba32> row = accessor.GetRowSpan(y);
            for (int x = 0; x < row.Length; x++)
            {
                ref Rgba32 pixel = ref row[x];
                // 如果接近白色,则改为黑色
                if (pixel.R > 240 && pixel.G > 240 && pixel.B > 240)
                {
                    pixel = new Rgba32(0, 0, 0, pixel.A);
                }
            }
        }
    });
    img.Save("processed.png");
}

这种方法避免了双重循环的性能开销,更加高效。

6. 元数据读写(EXIF / IPTC / XMP)

ImageSharp 支持读取和写入图像的元数据。例如,读取 IPTC 信息:

using (Image image = Image.Load("photo.jpg"))
{
    var iptc = image.Metadata.IptcProfile;
    if (iptc != null)
    {
        foreach (var val in iptc.Values)
        {
            Console.WriteLine($"{val.Tag}: {val.Value}");
        }
    }
}

写入 IPTC 元数据:

if (image.Metadata.IptcProfile == null)
    image.Metadata.IptcProfile = new SixLabors.ImageSharp.Metadata.Profiles.Iptc.IptcProfile();

image.Metadata.IptcProfile.SetValue(SixLabors.ImageSharp.Metadata.Profiles.Iptc.IptcTag.Caption, "这是图像说明");
image.Metadata.IptcProfile.SetValue(SixLabors.ImageSharp.Metadata.Profiles.Iptc.IptcTag.Keywords, "示例,测试");
image.Save("with_meta.jpg");

在不同环境中的应用

1. Web / ASP.NET Core 应用

在 ASP.NET Core 中,你可以将 ImageSharp 用于动态图像处理(如生成缩略图、水印、图片裁剪等)。此外,ImageSharp 还提供中间件支持,将其集成进请求管道中(特别适合用于静态资源或图像优化处理)。

Startup.csProgram.cs 中:

public void ConfigureServices(IServiceCollection services)
{
    services.AddImageSharp();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseImageSharp();     // 必须在 UseStaticFiles 之前
    app.UseStaticFiles();
    // …
}

这样在处理静态文件之前,你可以在 URL 上附带参数(如 ?width=200&format=png)来动态生成图像。

2. 控制台 / 后台批处理

在控制台或服务程序中,ImageSharp 非常适合做批量图片转换、压缩、处理等任务:

foreach (string path in Directory.EnumerateFiles("input_dir", "*.jpg"))
{
    using (Image img = Image.Load(path))
    {
        img.Mutate(x => x.Resize(1024, 0).Grayscale());
        string name = Path.GetFileNameWithoutExtension(path);
        img.Save(Path.Combine("output_dir", name + "_small.jpg"));
    }
}

3. 桌面 / WPF / WinForms

在桌面应用中,你可以使用 ImageSharp 生成或处理图像,然后将其转换为 System.Drawing.Bitmap 或 WPF 可用的 ImageSource 类型,以显示在界面上。通常需要将 ImageSharp 图像存为内存流,再转换:

using (var image = Image.Load("input.png"))
{
    using (var ms = new MemoryStream())
    {
        image.SaveAsPng(ms);
        ms.Position = 0;
        System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms);
        // 或在 WPF 中转换为 BitmapImage 等
    }
}

当然,如果你只在界面层显示而不做复杂渲染,有些平台可能更直接使用原生图形库,但 ImageSharp 在图像处理阶段具有无可比拟的灵活性。

性能优化建议与注意点

  1. 尽量使用 Mutate 链式操作
    多个操作可以合并在一次 Mutate(...) 调用中执行,避免重复分配。

  2. 使用 ProcessPixelRows 而非双重循环
    对于逐像素处理的场景,ProcessPixelRows 提供更高效的访问方式。

  3. 避免不必要的格式转换
    如果你以 Rgba32 加载图像,就持续使用这个格式处理,避免在中间转换像素格式导致开销。

  4. 注意内存和资源释放
    使用 using 或手动调用 .Dispose() 确保图像和流及时释放。

  5. 批量处理考虑并发
    对于大批量图像处理任务,可以使用异步或并行机制(如 Parallel.ForEach),但要注意线程安全和内存占用。

  6. 图像大小限制
    处理极大尺寸图像时,可能触及内存瓶颈。可考虑分块处理或下采样后处理。

总结

  • ImageSharp 是 .NET 平台上一款现代化、跨平台、高性能、易扩展的图像处理库。

  • 它支持丰富的格式、像素类型、元数据、滤镜与绘制操作,适用于多种场景。

  • 入门简单:加载、变换、保存三步即可完成基础图像处理。

  • 对于复杂操作(绘制、文字、逐像素调整、元数据读写等)也提供了强大的 API。

  • 在 Web、桌面、后台批处理场景中均适用,是 System.Drawing 在跨平台时代的理想替代方案。

顶部