必须设smoothingmode.antialias和textrenderinghint.cleartypegridfit,并按dpi缩放字号;居中需手动计算measurestring结果;logo叠加须用format32bpppargb并显式指定srcrect;禁用伽马校正防色偏;批量处理应复用font、缓存logo、预生成水印图层。

用 Graphics.DrawString 绘制文字水印时,字体缩放和抗锯齿容易出错
直接调用 Graphics.DrawString 往图片上写文字,常出现模糊、截断或位置偏移。根本原因是没正确设置 Graphics 的 SmoothingMode 和 TextRenderingHint,且未按目标图像 DPI 缩放字体大小。
- 务必在绘制前设
g.SmoothingMode = SmoothingMode.AntiAlias和g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit - 字体大小别硬写
12f,用new Font(fontFamily, fontSize * (image.HorizontalResolution / 96f))适配高 DPI 图像(Windows 默认 96 DPI) - 避免用
StringFormat.Alignment = StringAlignment.Center直接居中——它只对单行生效;多行需手动算MeasureString后偏移 - 文字颜色建议用半透明(如
Color.FromArgb(100, 0, 0, 0)),否则遮盖原图细节
用 Graphics.DrawImage 叠加 Logo 水印,透明通道丢失是高频问题
把 PNG Logo 叠到 JPG 原图上,结果 Logo 边缘发灰、阴影消失——大概率是源 Logo 的 Alpha 通道被忽略,或目标 Bitmap 创建时没指定 PixelFormat.Format32bppPArgb。
- 加载 Logo 必须用
Image.FromFile或Bitmap构造函数,不能用Image.FromStream后未重置流位置,否则读取为空 - 目标画布
Bitmap初始化时,显式传入PixelFormat.Format32bppPArgb,否则默认Format24bppRgb会丢弃 Alpha - 叠加时用
g.DrawImage(logo, destRect, srcRect, GraphicsUnit.Pixel),其中destRect建议带 5–10% 边距,避免贴边难看 - 若 Logo 尺寸远小于原图,先用
new Bitmap(logo, scaledSize)缩放再绘,别依赖DrawImage自动缩放——质量差且不控算法
Graphics 绘制后图片变暗或色彩偏移?检查 CompositingMode 和 CompositingQuality
叠加文字或 Logo 后整图饱和度下降、对比度变低,不是算法问题,而是 GDI+ 合成模式默认启用了伽马校正。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
- 在
Graphics实例创建后立即设g.CompositingMode = CompositingMode.SourceOver(默认值,但显式声明防误改) - 设
g.CompositingQuality = CompositingQuality.HighQuality,避免低质量合成引入色偏 - 关键:禁用伽马校正——
g.InterpolationMode = InterpolationMode.HighQualityBicubic之后,加一句g.PageScale = 1.0f,可抑制部分色彩漂移 - 如果仍偏色,导出前用
bitmap.Save(..., ImageFormat.Jpeg)时,传入EncoderParameters设置Encoder.Quality为 95 以上,低质量压缩会加剧失真
批量加水印卡顿?别在循环里反复 new Bitmap 和 Graphics.FromImage
处理上百张图时,每张都 new Bitmap() → Graphics.FromImage() → DrawString → Save(),内存暴涨、GC 频繁,速度骤降。
- 复用
Font对象:文字水印字体不变时,全局缓存一个Font实例,别每次 new - Logo 图片也缓存:用
static readonly Bitmap logo = new Bitmap("watermark.png"),避免重复解码 - 对同一尺寸原图,可预生成「水印图层」
Bitmap(含文字+Logo),再用DrawImage一次性合成,比逐帧绘制快 3–5 倍 - 真正瓶颈在磁盘 IO:用
FileStream的FileOptions.Asynchronous异步读写,配合Task.Run分离 CPU 密集型绘制
实际最难的不是 API 调用,是不同来源图片的 DPI、色彩空间、Alpha 支持程度不一致——测试时至少覆盖 JPG(无 Alpha)、PNG(带 Alpha)、WebP(可能含 ICC 配置文件)三类样本。










