C# 从WPF中的图像裁剪对角线区域

C# 从WPF中的图像裁剪对角线区域,c#,wpf,image,crop,resize-crop,C#,Wpf,Image,Crop,Resize Crop,我想在画布上使用用户绘制的矩形从图像中裁剪。矩形可以移动、重新调整大小和旋转 当用户选择“Get Cropped Image”时,矩形内的区域应保存在页面上的第二个图像位置,只要矩形不旋转,我就可以很好地保存该区域。(直接使用裁剪位图。)但是,当矩形成一定角度时,我不知道如何进行裁剪 这就是我想要做的(原谅我糟糕的MS绘画技巧): 我的问题是: 1) 如何正确跟踪或计算矩形的点 以及 2) 一旦有了这些点,如何裁剪旋转的矩形 编辑: 感谢用户,我相信我已经回答了第二个问题。使用从以下答案修改的

我想在画布上使用用户绘制的矩形从图像中裁剪。矩形可以移动、重新调整大小和旋转

当用户选择“Get Cropped Image”时,矩形内的区域应保存在页面上的第二个图像位置,只要矩形不旋转,我就可以很好地保存该区域。(直接使用裁剪位图。)但是,当矩形成一定角度时,我不知道如何进行裁剪

这就是我想要做的(原谅我糟糕的MS绘画技巧):

我的问题是:

1) 如何正确跟踪或计算矩形的点

以及

2) 一旦有了这些点,如何裁剪旋转的矩形

编辑: 感谢用户,我相信我已经回答了第二个问题。使用从以下答案修改的代码:,我看到了良好的结果。不幸的是,我仍然无法跟踪矩形的正确位置点,所以我还不能完全测试它

public static Bitmap CropRotatedRect(Bitmap source, System.Drawing.Rectangle rect, float angle, bool HighQuality)
 {
    Bitmap result = new Bitmap((int)rect.Width, (int)rect.Height);
    using (Graphics g = Graphics.FromImage(result))
     {
        g.InterpolationMode = HighQuality ? InterpolationMode.HighQualityBicubic : InterpolationMode.Default;
        using (Matrix mat = new Matrix())
         {
            mat.Translate(-rect.Location.X, -rect.Location.Y);
            mat.RotateAt(-(angle), rect.Location);
            g.Transform = mat;
            g.DrawImage(source, new System.Drawing.Point(0, 0));
         }
     }
    return result;
 }
编辑: 第一点的答案比我原先想象的要容易得多。通过调用-

double top = Canvas.GetTop(rect);
double left = Canvas.GetLeft(rect);
然后可以使用宽度和高度计算其余的点-

Point topLeft = new Point(left, top);
Point topRight = new Point(left + rect.Width, top);
Point bottomLeft = new Point(left, top + rect.Height);
Point bottomRight = new Point(left + rect.Width, top + rect.Height);
Point centerPoint = new Point(left + (rect.Width / 2), top + (rect.Height / 2));
如果旋转矩形,则必须平移这些点以确定它们在画布上的真实位置-

public Point TranslatePoint(Point center, Point p, double angle)
 { 
    // get the point relative to (0, 0) by subtracting the center of the rotated shape.
    Point relToOrig = new Point(p.X - center.X, p.Y - center.Y);
    double angleInRadians = angle * Math.PI / 180;
    double sinOfA = Math.Sin(angleInRadians);
    double cosOfA = Math.Cos(angleInRadians);
    Point translatedPoint = new Point(relToOrig.X * cosOfA - relToOrig.Y * sinOfA,
                                      relToOrig.X * sinOfA + relToOrig.Y * cosOfA);
    return new Point(translatedPoint.X + center.X, translatedPoint.Y + center.Y);
 }

一旦能够平移左上角,就可以使用Rotem的裁剪方法。您还可以计算矩形其余部分的位置,以便能够确定矩形是否在图像的边界内,是否与边缘接触,或者您可能希望对该位置执行的任何其他操作

我找到了我自己问题的答案,并在此过程中进行了适当的编辑。请看上面的答案

我找到了我自己问题的答案,并在此过程中进行了适当的编辑。请看上面的答案