5

I want to get some specific parts of an image so I'm cropping the images. However, when I want to get a part that is not parallel to the image, I rotate the image and crop afterwards.

I don't want to rotate the image and crop a parallel rectangle. What I want is, without rotating the image, to crop a rectangle with an angle from the image.

Is there any way to do that?

I think I couldnt express myself well enough. This is what I want to do: example picture.

Assume the red thing is a rectangle :) I want to crop that thing out of image. After cropping it doesn't need to be angeled. So mj can lie down.

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
user1125953
  • 585
  • 2
  • 7
  • 18
  • does this require a full 360 degrees rotation? or 90? – AlanFoster Jan 02 '12 at 09:26
  • it is not in a web-application. the degree changes actually, may be 32,90 whatever. – user1125953 Jan 02 '12 at 09:30
  • How are you currently defining the part you want to crop? A Rectangle and an angle? does the image rotate around it's center or around the center of the crop Rectangle? – Rotem Jan 02 '12 at 10:20
  • @rotem. i dont want to rotate the image. the image will stay as it is. but the rectangle i crop will be angled according to image. – user1125953 Jan 02 '12 at 10:56
  • I'm asking by what means can you define the area you want to crop? Is it a polygon, or a rectangle + angle? – Rotem Jan 02 '12 at 10:58
  • @rotem it is a rectangle+angle think of the "diamond" shape in paint. i want that but the difference is the shape is rectangle, and the angle between the x-axis and an edge of rectangle will be 45,37 whatever. I want to give that angle (and other rectangle information like width,heigth , x and y) and rotate the rectangle on its top left point on image – user1125953 Jan 02 '12 at 11:03
  • I think i couldnt express my self well enough. this is what i want to do : http://imageshack.us/photo/my-images/843/mjexample.jpg/ assume the red thing is a rectangle :) i want to crop that thing out of image. after cropping it doesn't need to be angeled. so mj can lie down – user1125953 Jan 02 '12 at 11:17
  • lol, how symbolic. I understand now what you are trying to do, I will try to write a code snippet to do it. – Rotem Jan 02 '12 at 11:24

1 Answers1

6

This method should perform what you asked for.

public static Bitmap CropRotatedRect(Bitmap source, Rectangle rect, float angle, bool HighQuality)
{
    Bitmap result = new Bitmap(rect.Width, 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 Point(0, 0));
        }
    }
    return result;
}

usage (using your MJ example):

Bitmap src = new Bitmap("C:\\mjexample.jpg");
Rectangle rect = new Rectangle(272, 5, 100, 350);
Bitmap cropped = CropRotatedRect(src, rect, -42.5f, true);
mrid
  • 5,782
  • 5
  • 28
  • 71
Rotem
  • 21,452
  • 6
  • 62
  • 109
  • Thank you so much. This works perfect. Just wondered that does this affect image quality at all? – user1125953 Jan 02 '12 at 12:37
  • It affects image quality just as any rotation (other than 90 degrees) inevitably affects the quality. If the answer is what you need please accept it as the answer. – Rotem Jan 02 '12 at 12:48
  • Sorry but i have to ask one more thing now :(. What can i do if the rectengle exceeds image dimension? Actually in that case i want to take the exceeding part from the back of the starting point. if i explaint it visually again :) it should be like : http://imageshack.us/photo/my-images/215/smoothcriminalleanexcee.jpg/ Actually it is still a rectangle as you see. Nothing has changed about the rectangle's size or starting point.. – user1125953 Jan 06 '12 at 12:27
  • I thought I understood what you want but your example confused me. Where is the starting point and what is that shape? – Rotem Jan 06 '12 at 15:14
  • Yeah you understood right but i forgot to tell this before.Actually nothing has changed. If you look carefully, when you merge these 2 parts from that weird puzzle like part, it is still a rectangle. What i want is still croping a rectangle. but when the image dimensions are exceeded i dont want to get a blank background color. I want to contuniue to crop. cropping from where? cropping from behind of starting edge as many as rectangle size needs. so it will finish where it is started. i hope i am clear enough – user1125953 Jan 06 '12 at 16:10
  • I think you mean you don't have free time for... :) I will appriciate if you can contribute. the new question link is: http://stackoverflow.com/questions/8785562/cropping-a-cross-rectangle-from-image-using-c-sharp – user1125953 Jan 09 '12 at 12:34
  • It's **crucial** that you you use the rectangle-overloaded version of `DrawImage` otherwise your image may be incorrectly scaled depending on the DPI. i.e., use: `g.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height));` instead. See http://stackoverflow.com/a/15712490/65387 – mpen Mar 29 '13 at 22:47
  • I stumbled across this and used this concept for a project I'm working on. I found I have to replace mat.RotateAt(angle, rect.Location); with mat.RotateAt(-angle, rect.Location); Otherwise it was rotating anti-clockwise instead of clockwise. I'm new to c# so I cannot enlighten anyone on the reasons for this but a heads up for anyone else who finds this. It was only after running a test pattern through this did I work out what it was doing. – chip Aug 25 '13 at 09:20