ImageSharp是跨平台加水印的推荐方案,因System.Drawing.Common在.NET 6+非Windows环境不兼容;需显式加载.ttf字体、用PNG水印图并保留Alpha通道,确保中文等字符正常显示。

直接用 System.Drawing 给图片加水印,不是最稳妥的选择——.NET 6+ 默认不支持 Windows Forms 相关绘图 API,Linux/macOS 下会直接抛 PlatformNotSupportedException;真要跨平台或部署到容器里,得换方案。
为什么 Graphics.DrawString 在 .NET 6+ 控制台项目里会崩
这不是你代码写错了,而是 System.Drawing.Common 的底层依赖(GDI+)在非 Windows 系统上不可用,且微软已明确标记该库为“legacy”。哪怕你装了包、加了 <usewindowsforms>true</usewindowsforms>,只要运行环境没 GUI 子系统(比如 Docker Alpine 镜像、Azure Functions Linux 实例),Graphics.FromImage 就会炸出 ObjectDisposedException 或空引用。
- 验证方式:在目标环境跑一句
Graphics.FromImage(new Bitmap(1, 1)),崩了就是环境不兼容 - 临时绕过:只在 Windows 开发机测试,但上线前必须切换方案
- 替代思路:改用纯托管的图像处理库,比如
SixLabors.ImageSharp
用 ImageSharp 给 PNG/JPEG 加文字水印(推荐)
SixLabors.ImageSharp 是零依赖、纯 C# 实现的图像库,.NET 5+ 原生支持,无平台限制。加文字水印的核心是两步:加载原图 → 绘制带透明度的文本图层。
- 安装包:
dotnet add package SixLabors.ImageSharp - 关键类:
Image<rgba32></rgba32>、TextOptions、FontCollection - 字体必须显式加载(不能靠系统字体名),否则报
FontFamilyNotFoundException - 示例片段(居中半透明水印):
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
<p>var image = Image.Load("input.jpg");
var font = new FontCollection().Install("./arial.ttf"); // 必须提供 .ttf 文件路径
var textOptions = new TextOptions(font.CreateFont("Arial", 48))
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Middle,
ApplyKerning = true,
GraphicsOptions = new GraphicsOptions { Antialias = true }
};</p><p>image.Mutate(x => x.DrawText("CONFIDENTIAL", textOptions, Color.ParseHex("#00000080"), new PointF(image.Width / 2f, image.Height / 2f)));
image.Save("output.png");
加图片水印比文字更简单,但要注意尺寸和透明通道
如果水印是 PNG(带 alpha),直接用 DrawImage 叠上去就行;但 JPEG 水印图会被当全不透明处理,导致背景发黑。关键点不在代码,而在输入文件本身。
- 确保水印图是 PNG 格式,且导出时保留 Alpha 通道(Photoshop 里存为“PNG-24,透明度勾选”)
- 缩放水印图时别用
Resize粗暴拉伸,要用Resize(new ResizeOptions { Mode = ResizeMode.Max, Size = new Size(200, 200) })保比例 - 叠加位置建议用相对坐标:比如右下角留边 20px,就传
new Point(image.Width - watermark.Width - 20, image.Height - watermark.Height - 20)
水印的透明度、字体抗锯齿、多语言字符(比如中文)渲染,都取决于你加载的字体文件是否包含对应字形——别指望系统字体自动 fallback,FontCollection.Install 失败时不会报错,只会静默用默认字体,结果可能显示成方块。


















