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

Posted

技术标签:

【中文标题】从 WPF 中的图像裁剪对角线区域【英文标题】:Crop a diagonal area from an image in WPF 【发布时间】:2015-12-24 16:33:38 【问题描述】:

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

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

这就是我想做的(原谅我糟糕的 MS Paint 技能):

我的问题是:

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

和,

2) 获得点后,如何裁剪旋转的矩形?

编辑: 感谢用户Rotem,相信我已经有了第二个问题的答案。使用从以下答案修改的代码:Answer 1、Answer 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 的裁剪方法。您还可以计算矩形其余部分的位置,这样您就可以确定矩形是否在图像的边界内,是否接触边缘,或者您可能想要做的任何其他事情位置。

【问题讨论】:

【参考方案1】:

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

【讨论】:

以上是关于从 WPF 中的图像裁剪对角线区域的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenCV 计算图像中所有不同区域的像素

WPF 图像裁剪

在 WPF 中相对于其容器绘制对角文本/文本块/标签/控件

[计算机图形学 with OpenGL] Chapter8 习题8.6 线段旋转后使用Cohen-Sutherland算法裁剪

如何在mysql查询中找到所选对角线区域之间的准确数据

Python使用matplotlib可视化分组多变量两两关系图使用seaborn中的pairplot函数可视化分组多变量两两关系图对角线为分组密度图其它图像为分组两两散点图