旋转图片框中的问题 [英] Problem in rotating picturebox

查看:84
本文介绍了旋转图片框中的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中有两个例外(错误)突然发生



1)参数无效

rotateBmp = new位图(nWidth,nHeight);



2)

g.DrawImage((Image)image.Clone(),内存不足,分数);



有时我会调用RotateImage1(..);在计时器(Windows.Form)

,其中增加角度为360,以旋转PictureBox图像。



  public   static 位图RotateImage1(图像, float 角度,表格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);

位图rotateBmp;

rotateBmp = new 位图(nWidth,nHeight);

使用(图形g = Graphics.FromImage(rotateBmp))
{
// 此数组将用于传递三个点
/ / 弥补旋转的图像
点[]点;
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)
};
}
其他 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
};
}
其他 if (locked_theta > = Math.PI&& locked_theta < (Math.PI + pi2))
{
points = new Point []
{
new Point(( int )adjacentTop,nHeight),
new Point( 0 ,( int )adjacentBottom),
new 点(nWidth,( int )oppositeTop)
};
}
其他
{
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 rotatingBmp;
}

解决方案

使用 PictureBox 。这个控件不会帮助你完成这个简单的任务,只会消耗一些额外的资源并占用一些额外的开发时间。相反,直接在某些控件上渲染图像,如 System.Windows.Forms.Panel ,或者您拥有从 System.Windows.Forms.Control派生的控件,这是通过处理事件 System.Windows.Forms.Control.Paint 或覆盖虚方法来完成的 System.Windows .Forms.Control.OnPaint



在这种情况下, System.Drawing.Graphics的实例在event arguments参数中传递给你。



已经由属性 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 [ ^ ]。



如您所见,您可以选择基于单个转换矩阵旋转角度和旋转中心。



另见我过去的答案:

在图片框中添加图片 [ ^ ],

用C#绘制一个矩形 [ ^ ],

如何从旧图纸中清除面板 [ ^ ],

什么样的俏皮方法是Paint? (DataGridViewImageCell.Paint(...)) [ ^ ],

在面板上捕获绘图 [ ^ ],

mdi子表单之间的绘制线 [ ^ ]。



-SA

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.

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

解决方案

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


这篇关于旋转图片框中的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆