C# 从两点裁剪图像(C) 更新:

C# 从两点裁剪图像(C) 更新:,c#,image,bitmap,crop,C#,Image,Bitmap,Crop,添加了更新的代码 但是由于某些原因,它仍然不能正常工作。如果坐标是位图坐标,原因是什么?我放在这里的第一个代码示例无法正常工作,第二个示例给我一个OutOfMemoryException 我在尝试在两点之间裁剪图像时遇到问题。在我的项目中,我有一个名为AP的pictureBox,一般的想法是用户点击两个点,程序在这两个角之间裁剪图像。我尝试过两种方法,一种是使用Bitmap.Crop,另一种是使用Graphics.DrawImage,但由于同样的原因,这两种方法都失败了,并且根本无法剪切图像的更

添加了更新的代码

但是由于某些原因,它仍然不能正常工作。如果坐标是位图坐标,原因是什么?我放在这里的第一个代码示例无法正常工作,第二个示例给我一个OutOfMemoryException

我在尝试在两点之间裁剪图像时遇到问题。在我的项目中,我有一个名为AP的pictureBox,一般的想法是用户点击两个点,程序在这两个角之间裁剪图像。我尝试过两种方法,一种是使用Bitmap.Crop,另一种是使用Graphics.DrawImage,但由于同样的原因,这两种方法都失败了,并且根本无法剪切图像的更小部分

代码:


由于裁剪后的位图图像大小与用户选择的宽度/高度相同,我猜您希望裁剪后的图像位于新位图的顶部/左侧并填充它。实际上,您告诉DrawImage方法在同一位置绘制位图的该部分,尽管是在较小尺寸的位图中

正确的方法是在0,0处绘制源矩形图像:

    private Point pt1, pt2;

    private void AP_Click(object sender, EventArgs e)
    {

        // ... obviously other code here ...            

        else if (mark_shape == 0) // Setting the corners
        {
            Point pt = AP.PointToClient(Cursor.Position);
            if (picture_corners_set == 0)
            {
                pt1 = new Point(pt.X, pt.Y);
                picture_corners_set = 1;
            }
            else if (picture_corners_set == 1)
            {
                pt2 = new Point(pt.X, pt.Y);
                picture_corners_set = 0;

                Rectangle imageRectangle = new Rectangle(new Point(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y)), new Size(Math.Abs(pt2.X - pt1.X) + 1, Math.Abs(pt2.Y - pt1.Y) + 1));
                var bmp = new Bitmap(imageRectangle.Width, imageRectangle.Height);
                using (var gr = Graphics.FromImage(bmp))
                {
                    gr.DrawImage(AP.Image, 0, 0, imageRectangle, GraphicsUnit.Pixel);
                }
                AP.Image = bmp;
                enableAllButtons();
            }
        }
    }

您还可以使用其他几种重载来实现这一点,但是上面的重载非常清楚地表明imageRectangle是在0,0处绘制的。

是相对于屏幕、窗体或picturebox的点坐标吗?我认为是相对于屏幕的点坐标;我将它们初始化为northEast=newpointmouseeventargs.X,mouseEventArgs.Y;由于位图裁剪坐标是相对于位图的,您是否在任何地方将鼠标坐标从屏幕坐标转换为客户端picturebox坐标?picturebox.PointToClient将屏幕坐标转换为客户端控制坐标,请参阅,我希望避免在构造函数中嵌套太多调用,这会使事情变得困难,但是,是的,差不多吧。将这两个点转换为TopLeft.X/Y和BottomRight.X/Y。请注意,PointToScreen需要一个点,而不仅仅是一个X或Y值。感谢您的回复,我已经使用PointToClient转换了坐标,但它仍然需要图像的一小部分并对其进行拉伸。我注意到图像的宽度和高度实际上都比我的屏幕分辨率大——这可能是个问题吗?我的电脑是1366*768,高度是1280,宽度是1832…用你用来设置分数的事件代码更新你原来的帖子。
    private Point pt1, pt2;

    private void AP_Click(object sender, EventArgs e)
    {

        // ... obviously other code here ...            

        else if (mark_shape == 0) // Setting the corners
        {
            Point pt = AP.PointToClient(Cursor.Position);
            if (picture_corners_set == 0)
            {
                pt1 = new Point(pt.X, pt.Y);
                picture_corners_set = 1;
            }
            else if (picture_corners_set == 1)
            {
                pt2 = new Point(pt.X, pt.Y);
                picture_corners_set = 0;

                Rectangle imageRectangle = new Rectangle(new Point(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y)), new Size(Math.Abs(pt2.X - pt1.X) + 1, Math.Abs(pt2.Y - pt1.Y) + 1));
                var bmp = new Bitmap(imageRectangle.Width, imageRectangle.Height);
                using (var gr = Graphics.FromImage(bmp))
                {
                    gr.DrawImage(AP.Image, 0, 0, imageRectangle, GraphicsUnit.Pixel);
                }
                AP.Image = bmp;
                enableAllButtons();
            }
        }
    }