C#中旋转Bitmap后追踪原图像点在新图像的位置方法
C# Bitmap旋转后原图像点的坐标映射方法
要追踪原图像上的点在旋转后新图像中的位置,核心是复现图像旋转时的完整变换逻辑,对目标点做相同的坐标变换,再修正到新图像的坐标系中。以下是针对你现有代码的具体实现方案:
一、梳理图像旋转的变换链
你的RotateImage方法对图像做了三步核心变换:
- 将原图像中心平移到坐标系原点(抵消后续旋转的偏移)
- 绕原点旋转指定角度
- 将旋转后的图像平移到新Bitmap的中心(适配扩展后的边界框)
要获取原图像点在新图像中的位置,需要对该点应用完全相同的变换流程。
二、原图像点到新图像的坐标映射实现
以原图像右上角(坐标(origBmp.Width, 0))为例,完整的坐标转换代码如下:
1. 核心转换方法
// 获取原图像点在旋转后图像中的坐标 public static PointF GetTransformedPoint(PointF originalPoint, Bitmap origBmp, float angle, out Rectangle boundingBox) { // 复现图像旋转的初始变换矩阵 Matrix transformMatrix = new Matrix(); transformMatrix.Translate(origBmp.Width / -2f, origBmp.Height / -2f, MatrixOrder.Append); transformMatrix.RotateAt(angle, new PointF(0, 0), MatrixOrder.Append); // 获取旋转后的图像边界框(和RotateImage方法中一致) boundingBox = BoundingBox(origBmp, transformMatrix); // 对原坐标应用变换 PointF[] transformedPoints = new PointF[] { originalPoint }; transformMatrix.TransformPoints(transformedPoints); // 修正到新图像的坐标系(平移到新Bitmap中心) return new PointF( transformedPoints[0].X + boundingBox.Width / 2f, transformedPoints[0].Y + boundingBox.Height / 2f ); }
2. 使用示例
Bitmap originalBmp = new Bitmap("original.png"); float rotateAngle = 45f; Bitmap rotatedBmp = RotateImage(originalBmp, rotateAngle); // 获取原图像右上角在新图像中的位置 Rectangle bbox; PointF topRightInRotated = GetTransformedPoint( new PointF(originalBmp.Width, 0), originalBmp, rotateAngle, out bbox );
三、风羽绘制的角度修正
要在旋转后的图像上正确绘制风羽,需要抵消图像旋转带来的坐标系偏移:
using (Graphics g = Graphics.FromImage(rotatedBmp)) { // 平移到目标点 g.TranslateTransform(topRightInRotated.X, topRightInRotated.Y); // 反向旋转图像角度,让风羽保持原数据的方向 g.RotateTransform(-rotateAngle); // 绘制风羽(示例:以(0,0)为起点绘制向右的风羽) g.DrawLine(Pens.Black, 0, 0, 30, 0); // 重置变换,避免影响后续绘制 g.ResetTransform(); }
关键注意事项
- 必须使用
PointF而非Point计算,避免整数坐标的精度丢失 - 变换矩阵的顺序要和
RotateImage方法完全一致(先平移到原点,再旋转) - 边界框计算复用现有
BoundingBox方法,保证和旋转后图像的尺寸匹配
内容的提问来源于stack exchange,提问作者Chris Gedling
相关产品推荐
相关产品推荐

