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
andrect.Height
have to be swapped. - It's often easiest to compute the new top or the new left using
bitmap.Width-rect.Right
andbitmap.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;
}
}
精彩评论