Chinaunix首页 | 论坛 | 博客
  • 博客访问: 318807
  • 博文数量: 23
  • 博客积分: 2115
  • 博客等级: 大尉
  • 技术积分: 371
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-15 16:36
文章分类

全部博文(23)

文章存档

2013年(4)

2012年(4)

2011年(3)

2010年(6)

2009年(5)

2008年(1)

我的朋友

分类: C/C++

2009-03-05 13:37:55

用C# GDI+进行位图(Bitmap)旋转的代码,已经封装成了一个静态函数~

public static Bitmap RotateImage(Image image, float angle)
        {
            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) image.Width;
            double oldHeight = (double) image.Height;
            
            // 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


            Explaination of the calculations

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

                }
                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 )
                                         };
                }
                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 )
                                         };
                }
                else
                {
                    points = new Point[] {
                                             new Point( 0, (int) adjacentBottom ),
                                             new Point( (int) oppositeBottom, 0 ),
                                             new Point( (int) adjacentTop, nHeight )
                                         };
                }

                g.DrawImage(image, points);
            }

            return rotatedBmp;
        }

阅读(5095) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:GDI+中位图颜色替换

给主人留下些什么吧!~~