您的位置:首页 > 编程语言

图片旋转--修改老外的代码,返回中增加第四个顶点

2013-05-02 11:39 477 查看
public static Bitmap RotateImage(Image image, int iw, int ih, float angle, out Point[] points)
{
if (image == null)
throw new ArgumentNullException("image");

const double pi2 = Math.PI / 2.0;

// Why can't C# allow these to be const, or at least readonly
// *sigh*  I'm starting to talk like Christian Graus :omg:
double oldWidth = (double)iw;
double oldHeight = (double)ih;

// Convert degrees to radians
double theta = ((double)angle) * Math.PI / 180.0;
double locked_theta = theta;

// Ensure theta is now [0, 2pi)
while (locked_theta < 0.0)
locked_theta += 2 * Math.PI;

double newWidth, newHeight;
int nWidth, nHeight; // The newWidth/newHeight expressed as ints

double adjacentTop, oppositeTop;
double adjacentBottom, oppositeBottom;

// We need to calculate the sides of the triangles based
// on how much rotation is being done to the bitmap.
//   Refer to the first paragraph in the explaination above for
//   reasons why.
if ((locked_theta >= 0.0 && locked_theta < pi2) ||
(locked_theta >= Math.PI && locked_theta < (Math.PI + pi2)))
{
adjacentTop = Math.Abs(Math.Cos(locked_theta)) * oldWidth;
oppositeTop = Math.Abs(Math.Sin(locked_theta)) * oldWidth;

adjacentBottom = Math.Abs(Math.Cos(locked_theta)) * oldHeight;
oppositeBottom = Math.Abs(Math.Sin(locked_theta)) * oldHeight;
}
else
{
adjacentTop = Math.Abs(Math.Sin(locked_theta)) * oldHeight;
oppositeTop = Math.Abs(Math.Cos(locked_theta)) * oldHeight;

adjacentBottom = Math.Abs(Math.Sin(locked_theta)) * oldWidth;
oppositeBottom = Math.Abs(Math.Cos(locked_theta)) * oldWidth;
}

newWidth = adjacentTop + oppositeBottom;
newHeight = adjacentBottom + oppositeTop;

nWidth = (int)Math.Ceiling(newWidth);
nHeight = (int)Math.Ceiling(newHeight);

Bitmap rotatedBmp = new Bitmap(nWidth, nHeight);

using (Graphics g = Graphics.FromImage(rotatedBmp))
{
// This array will be used to pass in the three points that
// make up the rotated image
//Point[] points;

/*
* The values of opposite/adjacentTop/Bottom are referring to
* fixed locations instead of in relation to the
* rotating image so I need to change which values are used
* based on the how much the image is rotating.
*
* For each point, one of the coordinates will always be 0,
* nWidth, or nHeight.  This because the Bitmap we are drawing on
* is the bounding box for the rotated bitmap.  If both of the
* corrdinates for any of the given points wasn't in the set above
* then the bitmap we are drawing on WOULDN'T be the bounding box
* as required.
*/
if (locked_theta >= 0.0 && locked_theta < pi2)
{
points = new Point[] {
new Point( (int) oppositeBottom, 0 ),
new Point( nWidth, (int) oppositeTop ),
new Point( 0, (int) adjacentBottom),
new Point((int)(nWidth - oppositeBottom), (int)(oppositeTop + adjacentBottom))
};

}
else if (locked_theta >= pi2 && locked_theta < Math.PI)
{
points = new Point[] {
new Point( nWidth, (int) oppositeTop ),
new Point( (int) adjacentTop, nHeight ),
new Point( (int) oppositeBottom, 0 ),
new Point((int)(oppositeBottom - (nWidth-adjacentTop)), (int)(nHeight - oppositeTop))
};
}
else if (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2))
{
points = new Point[] {
new Point( (int) adjacentTop, nHeight ),
new Point( 0, (int) adjacentBottom ),
new Point( nWidth, (int) oppositeTop ),
new Point((int)(nWidth - adjacentTop), (int)(oppositeTop + adjacentBottom - nHeight))
};
}
else
{
points = new Point[] {
new Point( 0, (int) adjacentBottom ),
new Point( (int) oppositeBottom, 0 ),
new Point( (int) adjacentTop, nHeight ),
new Point((int)(adjacentTop + oppositeBottom), (int)(nHeight - adjacentBottom))
};
}

Point[] ps = new Point[] { points[0], points[1], points[2] };
g.DrawImage(image, ps);
}

return rotatedBmp;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: