You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将旋转图形中的矩形区域复制到另一旋转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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 19:27:52