如何将旋转图形中的矩形区域复制到另一旋转Graphics对象?
实现旋转矩形区域的复制与粘贴
需求:从一张图像中复制旋转状态的矩形区域(如倾斜车牌),粘贴到同尺寸另一张图像的对应位置,用于模糊敏感区域时保留特定旋转元素。非旋转场景已通过DrawImage实现,但旋转场景的两次尝试均失败。
错误原因分析
- 第一种方法错误对源图的
Graphics做变换,但源图本身未被修改,DrawImage仍调用原始Bitmap,因此无旋转效果。 - 第二种方法通过
new Bitmap(width, height, g)创建Bitmap的方式无效,该构造函数仅用于指定像素格式关联,无法捕获Graphics的绘制内容。
解决方案思路
正确逻辑是先提取源图中的目标矩形区域,对该区域单独旋转,再将旋转后的图像对齐原区域中心绘制到目标图,需计算旋转后图像的边界尺寸,避免内容被裁剪。
实现代码
public static void CopyRotatedRegion(Bitmap sourceBitmap, Graphics destGraphics, Rectangle sourceRect, float rotationAngle) { // 1. 从源图裁剪出目标矩形区域 using (Bitmap croppedBitmap = sourceBitmap.Clone(sourceRect, sourceBitmap.PixelFormat)) { // 2. 计算旋转后图像的边界尺寸,防止内容被裁剪 float radians = rotationAngle * (float)Math.PI / 180; float cos = Math.Abs((float)Math.Cos(radians)); float sin = Math.Abs((float)Math.Sin(radians)); int rotatedWidth = (int)(croppedBitmap.Width * cos + croppedBitmap.Height * sin); int rotatedHeight = (int)(croppedBitmap.Width * sin + croppedBitmap.Height * cos); // 3. 创建容纳旋转后图像的Bitmap using (Bitmap rotatedBitmap = new Bitmap(rotatedWidth, rotatedHeight)) { using (Graphics g = Graphics.FromImage(rotatedBitmap)) { // 设置高质量绘制参数 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; // 4. 平移到旋转中心→执行旋转→平移回原点 g.TranslateTransform(rotatedWidth / 2f, rotatedHeight / 2f); g.RotateTransform(rotationAngle); g.TranslateTransform(-croppedBitmap.Width / 2f, -croppedBitmap.Height / 2f); // 将裁剪区域绘制到旋转后的Bitmap g.DrawImage(croppedBitmap, 0, 0); } // 5. 计算目标图上的绘制位置:以原矩形中心对齐旋转后图像的中心 PointF destCenter = new PointF(sourceRect.X + sourceRect.Width / 2f, sourceRect.Y + sourceRect.Height / 2f); PointF destTopLeft = new PointF(destCenter.X - rotatedWidth / 2f, destCenter.Y - rotatedHeight / 2f); // 6. 将旋转后的图像绘制到目标图 destGraphics.DrawImage(rotatedBitmap, destTopLeft); } } }
代码说明
- 先裁剪源区域,避免对整张图做变换,提升效率。
- 计算旋转后尺寸,确保旋转后的内容完整显示。
- 绕裁剪区域自身中心旋转,保证旋转逻辑正确。
- 基于原矩形中心对齐旋转后图像,确保粘贴位置与原区域对应。
使用示例
假设resultImage是目标图,firstImage是源图,rotatedPlateRect是旋转的车牌矩形,rotationAngle为旋转角度:
using (var g = Graphics.FromImage(resultImage)) { // 先执行模糊敏感区域的操作 // ... // 粘贴旋转的车牌区域 CopyRotatedRegion(firstImage, g, rotatedPlateRect, 15f); }
内容的提问来源于stack exchange,提问作者Simas Paškauskas
相关产品推荐
相关产品推荐

