Вращение и переворот прямоугольника - PullRequest
0 голосов
/ 26 августа 2011

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

Например, если у меня есть растровое изображение 1000 x 800 пикселей, на нем может быть нарисован объект Rectangle с указанной точкой и размером.

Пример кода:

// A bitmap that's 1000x800 size
Bitmap bitmap = new Bitmap(fileName); 

// Any arbitrary rectangle that can be drawn inside the bitmap boundaries
Rectangle rect = new Rectangle(200, 200, 100, 100);

bitmap.RotateFlip(rotateFlipType);

switch (rotateFlipType)
{
    case Rotate90FlipNone:
        // Adjust rectangle to match new bitmap orientation
        rect = new Rectangle(?, ?, ?, ?);
        break;
    case RotateNoneFlip180:
        rect = new Rectangle(?, ?, ?, ?);
        break;
    // ... etc.
}

Ответы [ 2 ]

1 голос
/ 26 августа 2011

Мне проще всего рассуждать по каждому сценарию, рисуя картинку и помечая rect.Top, rect.Bottom, rect.Left и rect.Right.Как только это будет сделано, я либо мысленно поверну картинку, либо даже физически поверну бумагу.Оттуда это так же просто, как выяснить, где живут новые rect.Left и rect.Top.

Несколько общих советов:

  • Для поворота на 90 и 270 градусов, rect.Width и rect.Height необходимо поменять местами.
  • Часто проще всего вычислить новую вершину или новую левую, используя bitmap.Width-rect.Right и bitmap.Height-rect.Bottom.

Вот вашидва примера с заполненными пробелами, чтобы вы начали:

switch (rotateFlipType)
{
    case Rotate90FlipNone:
        // Adjust rectangle to match new bitmap orientation
        rect = new Rectangle(bitmap.Height-rect.Bottom, 
                             rect.Left,
                             rect.Height,
                             rect.Width);
        break;
    case RotateNoneFlipHorizontally:
        rect = new Rectangle(bitmap.Width - rect.Right,
                             rect.Top,
                             rect.Width,
                             rect.Height);
        break;
    // ... etc.
}
0 голосов
/ 08 мая 2015

Я столкнулся именно с этой проблемой.

Вот мои результаты - возможно, они спасут кого-то еще час возни ...

void RotateFlipRect(CRect & pRect, int pNewContainerWidth, int pNewContainerHeight, Gdiplus::RotateFlipType pCorrection)
{
  CRect lTemp = pRect;

  switch (pCorrection)
  {
    case    RotateNoneFlipNone: // = Rotate180FlipXY
      break;
    case         Rotate90FlipNone:  // = Rotate270FlipXY
      pRect.left = lTemp.top;
      pRect.top = pNewContainerHeight - lTemp.right;
      pRect.right = lTemp.bottom;
      pRect.bottom = pNewContainerHeight - lTemp.left;
      break;
    case         Rotate180FlipNone: // = RotateNoneFlipXY
      pRect.left = pNewContainerWidth - lTemp.right;
      pRect.top = pNewContainerHeight - lTemp.bottom;
      pRect.right = pNewContainerWidth - lTemp.left;
      pRect.bottom = pNewContainerHeight - lTemp.top;
      break;
    case         Rotate270FlipNone: // = Rotate90FlipXY
      pRect.left = pNewContainerWidth - lTemp.bottom;
      pRect.top = lTemp.left;
      pRect.right = pNewContainerWidth - lTemp.top;
      pRect.bottom = lTemp.right;
      break;
    case         RotateNoneFlipX: // = Rotate180FlipY
      pRect.left = pNewContainerWidth - lTemp.right;
      pRect.top = lTemp.top;
      pRect.right = pNewContainerWidth - lTemp.left;
      pRect.bottom = lTemp.bottom;
      break;
    case         Rotate90FlipX: // = Rotate270FlipY
      pRect.left = pNewContainerWidth - lTemp.bottom;
      pRect.top = pNewContainerHeight - lTemp.right;
      pRect.right = pNewContainerWidth - lTemp.top;
      pRect.bottom = pNewContainerHeight - lTemp.left;
      break;
    case         Rotate180FlipX: // = RotateNoneFlipY
      pRect.left = lTemp.left;
      pRect.top = pNewContainerHeight - lTemp.bottom;
      pRect.right = lTemp.right;
      pRect.bottom = pNewContainerHeight - lTemp.top;
      break;
    case         Rotate270FlipX:  // = Rotate90FlipY
      pRect.left = lTemp.top;
      pRect.top = lTemp.left;
      pRect.right = lTemp.bottom;
      pRect.bottom = lTemp.right;
      break;
    default:
      // ?!??!
      break;
  }
}
...