用Graphics.RotateTransform做任意角度旋转需三步:先平移原点至图像中心,再旋转,最后反向平移或居中绘制;Bitmap.RotateFlip仅支持90°整数倍旋转与固定翻转组合,不适用于任意角度。

用 Graphics.RotateTransform 做任意角度旋转,但必须配合坐标系平移
直接调用 RotateTransform 会让图片绕画布左上角(0,0)旋转,结果多半是图“转飞了”——只看到四分之一甚至完全不见。根本原因是没把旋转中心移到图片中心。
正确做法是三步:先平移原点到图片中心 → 旋转 → 再平移回原点(或直接绘制到新 Bitmap 中心)。实际写时更推荐新建一个和原图等大的 Bitmap,用 Graphics 在其上操作:
- 创建目标
Bitmap,尺寸建议按旋转后外接矩形计算(否则裁边),可用Math.Abs(Math.Cos(angle)) * w + Math.Abs(Math.Sin(angle)) * h粗略估算宽高 - 用
g.TranslateTransform(w / 2f, h / 2f)把原点移到中心 - 再调
g.RotateTransform(angle)(angle是度数,顺时针为正) - 最后
g.DrawImage时偏移-w/2f, -h/2f,让图像居中绘制
Bitmap.RotateFlip 只支持 90° 倍数旋转和镜像,别想用它转 30°
这个方法快、安全、一行搞定,但能力严格受限:RotateFlipType 枚举只有 12 种组合,全是 RotateNoneFlipX、Rotate180FlipNone 这类固定动作。传非标准值会抛 ArgumentException。
典型误用场景:想水平翻转+旋转 45°,结果硬套 RotateFlip 失败。记住它只做两件事:旋转(0/90/180/270)+ 翻转(X/Y/XY),不能混搭任意角度。
- 水平翻转 =
RotateFlipType.RotateNoneFlipX - 垂直翻转 =
RotateFlipType.RotateNoneFlipY - 先水平再垂直翻转 =
RotateFlipType.RotateNoneFlipXY(等价于 180° 旋转) - 想同时翻转+任意角度旋转?必须用
Graphics方案,RotateFlip不参与
翻转本质是缩放,用 ScaleTransform(-1, 1) 更灵活
水平翻转不是“镜像命令”,而是对 X 轴做 -1 倍缩放;垂直翻转同理是 Y 轴缩放 -1。这个理解能帮你统一处理翻转+旋转的复合变换。
比如要“先水平翻转,再顺时针转 30°”,顺序很重要:先 ScaleTransform(-1, 1),再 RotateTransform(30),否则旋转方向会反。矩阵乘法不可交换,顺序错了图像就歪了。
- 仅水平翻转:用
g.ScaleTransform(-1, 1)后,DrawImage的 X 坐标得取负(如-x),否则图跑到画布外 - 仅垂直翻转:用
g.ScaleTransform(1, -1),Y 坐标也得取负 - 如果不想手动调坐标,就在缩放前
TranslateTransform(w, 0)(水平翻转时)或TranslateTransform(0, h)(垂直翻转时),把负轴拉回可视区
注意 Bitmap 构造和 Graphics 生命周期,常见黑图/空图问题都出在这儿
最常踩的坑:新建 Bitmap 后没用 Graphics.FromImage 获取绘图上下文,或者用了但忘了 Dispose(),导致后续绘制无效或内存泄漏。还有一种情况是源图带 Alpha 通道,但目标 Bitmap 用的是 PixelFormat.Format24bppRgb,透明部分变黑。
- 务必用
new Bitmap(w, h, PixelFormat.Format32bppPArgb)——PArgb支持 Alpha,且性能比Argb更好 -
Graphics对象必须显式Dispose(),用using最稳妥 - 源图如果是 PNG 或带透明色,别用
GetPixel/SetPixel逐点操作,极慢且易丢 Alpha;坚持走DrawImage+Graphics变换流 - 旋转后图像模糊?试试在
Graphics上设g.InterpolationMode = InterpolationMode.HighQualityBicubic和g.SmoothingMode = SmoothingMode.AntiAlias
GDI+ 的图像变换本质是矩阵运算,所有操作都在内存里改坐标映射。真正难的不是写哪行代码,而是想清楚“我想让哪个点变成新图像的 (0,0),旋转中心该锚在哪,缩放后坐标系正负方向是否一致”。这些不厘清,参数调十遍也没用。











