Обрезка поперечного прямоугольника с изображения с помощью c # - PullRequest
1 голос
/ 09 января 2012

Что я хочу сделать - это обрезать прямоугольник на изображении.Однако это должно удовлетворять некоторым особым случаям:

  1. Я хочу обрезать угловой прямоугольник на изображении.
  2. Я не хочу вращать изображение и обрезать прямоугольник:)
  3. Если обрезка превышает размер изображения, я не хочу обрезать пустой цвет фона.

Я хочу обрезать заднюю точку, которая закончится в начальной точке, когда размер прямоугольника будет завершен.Я знаю, что не смог бы хорошо объяснить, поэтому, если я покажу то, что хочу визуально:

enter image description here

Синяя точка является отправной точкой, а стрелка показывает направление обрезки.Когда обрезка превышает границы изображения, она возвращается к задней части начальной точки так же, как когда ширина и высота прямоугольника закончились, конец прямоугольника будет в начальной точке.

Кроме того, это предыдущийвопрос, который я задал:

В этом вопросе я не мог предсказать, чтоможет возникнуть проблема с размерами изображения, поэтому я не просил об этом.Но теперь есть случай 3. За исключением случая три, это точно такой же вопрос.Как я могу это сделать, какие-либо предложения?

1 Ответ

1 голос
/ 09 января 2012

Что нужно сделать, это добавить смещения к выравниванию матрицы. В этом случае я беру по одной дополнительной длине прямоугольника с каждой стороны (всего 9 прямоугольников) и смещаю матрицу каждый раз.

Обратите внимание, что необходимо поместить смещение 0 (исходная обрезка) последним, иначе вы получите неправильный результат.

Также обратите внимание, что если вы укажете прямоугольник, который больше повернутого изображения, вы все равно получите пустые области.

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;
}

Чтобы воссоздать ваш пример:

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