开发者

Rectangle Rotation and Flipping

I have a bitmap with a Rectangle object that is drawn on top of it. I want to be able to Rot开发者_开发技巧ateFlip the bitmap and adjust the x, y, width, and height of the Rectangle so that it lines up with the bitmap after each rotation or flip.

For example, if I have a bitmap of 1000 x 800 pixels, I may have a Rectangle object being drawn on it with a specified point and size.

Sample code:

// 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.
}


I find it easiest to reason through each scenario by drawing a picture and labeling rect.Top, rect.Bottom, rect.Left, and rect.Right. Once that's done, I either mentally rotate the picture, or even physically rotate the paper. From there, it's as simple as figuring out where the new rect.Left and rect.Top live.

A few general tips:

  • For 90 degree and 270 degree rotations, rect.Width and rect.Height have to be swapped.
  • It's often easiest to compute the new top or the new left using bitmap.Width-rect.Right and bitmap.Height-rect.Bottom.

Here are your two examples with the blanks filled in to get you started:

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


I faced exactly this problem.

Here are my results - perhaps they will save somebody else an hour of fiddling...

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜