Click here to Skip to main content
16,012,821 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
In below code there are two exceptions(error) which occurs suddenly

1)Parameter is not valid in
rotatedBmp = new Bitmap(nWidth, nHeight);

2)Out of memory in
g.DrawImage((Image)image.Clone(), points);

Error occurs sometimes i am calling RotateImage1(..); in timer(Windows.Form)
which increment angle to 360 in order to rotate PictureBox image.

C#
public static Bitmap RotateImage1(Image image, float angle, Form f)
{
   if (image == null)
      throw new ArgumentNullException("image");

   const double pi2 = Math.PI / 2.0;
   double oldWidth = Convert.ToDouble(420);
   double oldHeight = Convert.ToDouble(420);
   double theta = ((double)angle) * Math.PI / 180.0;
   double locked_theta = theta;
   while (locked_theta < 0.0)
      locked_theta += 2 * Math.PI;

   double newWidth, newHeight;
   int nWidth, nHeight; 
   double adjacentTop, oppositeTop;
   double adjacentBottom, oppositeBottom;
   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;
          
   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;
      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)image.Clone(), points);
   }

   return rotatedBmp;
}
Posted
Updated 8-Nov-14 12:40pm
v2

1 solution

It's possible but absolutely pointless to rotate something using PictureBox. This control won't help you to accomplish this simple task, will only consume some extra resources and take up some extra development time. Instead, render the image directly on some control like System.Windows.Forms.Panel or you own control derived from System.Windows.Forms.Control, which is done by handling the event System.Windows.Forms.Control.Paint or overriding the virtual method System.Windows.Forms.Control.OnPaint.

In this case, the instance of System.Drawing.Graphics is passed to you in the event arguments parameter.

Rotation is already done for you by the property System.Drawing.Graphics.Transform:
http://msdn.microsoft.com/en-us/library/system.drawing.graphics.transform(v=vs.110).aspx[^],
http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.matrix(v=vs.110).aspx[^],
http://msdn.microsoft.com/en-us/library/a0z3f662%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/System.Drawing.Drawing2D.Matrix.Rotate%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.matrix.rotateat%28v=vs.110%29.aspx[^].

As you can see, you can choose a single transformation matrix based on rotation angle and the center of rotation.

See also my past answers:
Append a picture within picturebox[^],
draw a rectangle in C#[^],
How do I clear a panel from old drawing[^],
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^],
capture the drawing on a panel[^],
Drawing Lines between mdi child forms[^].

—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900