Cropping a cross rectangle from image using c#

喜夏-厌秋 提交于 2019-12-02 09:25:00

问题


What I want to do is basically cropping a rectangle from an image. However, it should satisfy some special cases:

  1. I want to crop an angled rectangle on image.
  2. I don't want to rotate the image and crop a rectangle :)
  3. If cropping exceeds the image size, I don't want to crop an empty background color.

I want to crop from back of the starting point, that will end at starting point when rectangle size completed. I know I couldn't explain well so if I show what I want visually:

The blue dot is the starting point there, and the arrow shows cropping direction. When cropping exceeds image borders, it will go back to the back of the starting point as much as, when the rectangle width and height finished the end of the rectangle will be at starting point.

Besides this is the previous question I asked:

  • How to crop a cross rectangle from an image using c#?

In this question, I couldn't predict that a problem can occur about image dimensions so I didn't ask for it. But now there is case 3. Except case three, this is exactly same question. How can I do this, any suggestions?


回答1:


What needs to be done is to add offsets to the matrix alignment. In this case I am taking one extra length of the rectangle from each side (total 9 rectangles) and offsetting the matrix each time.

Notice that it is necessary to place offset 0 (the original crop) last, otherwise you will get the wrong result.

Also note that if you specify a rectangle that is bigger than the rotated picture you will still get empty areas.

public static Bitmap CropRotatedRect(Bitmap source, Rectangle rect, float angle, bool HighQuality)
{
    int[] offsets = { -1, 1, 0 }; //place 0 last!
    Bitmap result = new Bitmap(rect.Width, rect.Height);
    using (Graphics g = Graphics.FromImage(result))
    {
        g.InterpolationMode = HighQuality ? InterpolationMode.HighQualityBicubic : InterpolationMode.Default;
        foreach (int x in offsets)
        {
            foreach (int y in offsets)
            {
                using (Matrix mat = new Matrix())
                {
                    //create the appropriate filler offset according to x,y
                    //resulting in offsets (-1,-1), (-1, 0), (-1,1) ... (0,0)
                    mat.Translate(-rect.Location.X - rect.Width * x, -rect.Location.Y - rect.Height * y);
                    mat.RotateAt(angle, rect.Location);
                    g.Transform = mat;
                    g.DrawImage(source, new Point(0, 0));
                }
            }
        }
    }
    return result;
}

To recreate your example:

Bitmap source = new Bitmap("C:\\mjexample.jpg");
Bitmap dest = CropRotatedRect(source, new Rectangle(86, 182, 87, 228), -45, true);


来源:https://stackoverflow.com/questions/8785562/cropping-a-cross-rectangle-from-image-using-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!