简体   繁体   English

从两点中裁剪图像(C#)

[英]Crop image out of two points (C#)

Update: 更新:

Updated code added. 添加了更新的代码。

However for some reason it still doesn't work properly. 但是由于某种原因,它仍然无法正常工作。 If the coordinates are Bitmap coordinates, what could be the reason? 如果坐标是位图坐标,可能是什么原因? The first code sample I put here doesn't work properly and the second gives me an OutOfMemoryException. 我在这里放置的第一个代码示例无法正常工作,第二个代码示例给出了OutOfMemoryException。

I've ran into a problem trying to crop an image between two points. 我在尝试在两点之间裁剪图像时遇到问题。 In my project I have a pictureBox (named AP), and the general idea is that the user clicks on two points and the program crops the image between these two corners. 在我的项目中,我有一个pictureBox(名为AP),通常的想法是用户单击两个点,然后程序在这两个角之间裁剪图像。 I've tried two methods, one with Bitmap.Crop and the other one with Graphics.DrawImage, but both seemed to fail for the same reason and didn't work at all (cropped a much smaller portion of the image). 我尝试了两种方法,一种是使用Bitmap.Crop,另一种是使用Graphics.DrawImage,但是由于相同的原因,两种方法似乎都失败了,而且根本不起作用(裁剪了图像的一小部分)。

Code: 码:

    private void AP_Click(object sender, EventArgs e)
    {
        // Setting the corners
        else if (mark_shape == 0)
        {
            var mouseEventArgs = e as MouseEventArgs;
            if (picture_corners_set == 0)
            {
                northEast = AP.PointToClient(new Point(mouseEventArgs.X, mouseEventArgs.Y));
                picture_corners_set = 1;
            }
            else if (picture_corners_set == 1)
            {
                southWest = AP.PointToClient(new Point(mouseEventArgs.X, mouseEventArgs.Y));
                Rectangle imageRectangle = new Rectangle(southWest.X, northEast.Y, (northEast.X - southWest.X), (southWest.Y - northEast.Y));
                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();
            }
        }
    }

Since your cropped Bitmap image size is the same as the width/height of the user selection, I'm guessing you want that cropped image to be in the top/left of the new Bitmap and fill it. 由于裁剪后的位图图像大小与用户选择的宽度/高度相同,因此我猜测您希望裁剪后的图像位于新位图的顶部/左侧并填充它。 As it is, you're telling the DrawImage() method to draw that portion of the Bitmap in the same location, albeit in a smaller size Bitmap. 照原样,您要告诉DrawImage()方法将Bitmap的该部分绘制在相同位置,尽管使用较小的Bitmap。

The correct way to do this is to draw the source rectangle image at (0, 0): 正确的方法是在(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();
            }
        }
    }

There are several other overloads you could use to do this, but the one above makes it pretty clear that imageRectangle is being drawn at (0, 0). 您还可以使用其他几个重载来执行此操作,但是上面的一个重载可以很清楚地看到imageRectangle是在(0,0)处绘制的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM