2012-05-03 2 views
0

J'essaie d'utiliser la combinaison de la classe timer et d'un codeproject pour faire pivoter une image en douceur dans un contrôle de zone d'image (Visual Studio 2010 C#). Le problème que j'ai est soit l'image ne tourne pas ou je reçois une exception de threading. Quelque chose à propos de "l'objet est utilisé ailleurs". Voici les principales parties du code, j'apprécierais grandement toute aide que vous pouvez fournir. Je vous remercie.Rotation d'une image en continu sur un formulaire Windows

private void Form1_Load(object sender, EventArgs e) 
    { 
     timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
     timer.Start(); 
    } 

    private void timer_Elapsed(object sender, EventArgs e) 
    { 
     //Graphics graphic = Graphics.FromImage(pictureBox1.Image); 
     //graphic.RotateTransform(45); 


     this.Invoke(new MethodInvoker(delegate { RotateImage(pictureBox1.Image, 10); }));  

    } 



    public static Bitmap RotateImage(Image image, float angle) 
    { 
     // center of the image 
     float rotateAtX = image.Width/2; 
     float rotateAtY = image.Height/2; 
     bool bNoClip = false; 
     return RotateImage(image, rotateAtX, rotateAtY, angle, bNoClip); 
    } 

    public static Bitmap RotateImage(Image image, float angle, bool bNoClip) 
    { 
     // center of the image 
     float rotateAtX = image.Width/2; 
     float rotateAtY = image.Height/2; 
     return RotateImage(image, rotateAtX, rotateAtY, angle, bNoClip); 
    } 

    public static Bitmap RotateImage(Image image, float rotateAtX, float rotateAtY, float angle, bool bNoClip) 
    { 
     int W, H, X, Y; 
     if (bNoClip) 
     { 
      double dW = (double)image.Width; 
      double dH = (double)image.Height; 

      double degrees = Math.Abs(angle); 
      if (degrees <= 90) 
      { 
       double radians = 0.0174532925 * degrees; 
       double dSin = Math.Sin(radians); 
       double dCos = Math.Cos(radians); 
       W = (int)(dH * dSin + dW * dCos); 
       H = (int)(dW * dSin + dH * dCos); 
       X = (W - image.Width)/2; 
       Y = (H - image.Height)/2; 
      } 
      else 
      { 
       degrees -= 90; 
       double radians = 0.0174532925 * degrees; 
       double dSin = Math.Sin(radians); 
       double dCos = Math.Cos(radians); 
       W = (int)(dW * dSin + dH * dCos); 
       H = (int)(dH * dSin + dW * dCos); 
       X = (W - image.Width)/2; 
       Y = (H - image.Height)/2; 
      } 
     } 
     else 
     { 
      W = image.Width; 
      H = image.Height; 
      X = 0; 
      Y = 0; 
     } 

     //create a new empty bitmap to hold rotated image 
     Bitmap bmpRet = new Bitmap(W, H); 
     bmpRet.SetResolution(image.HorizontalResolution, image.VerticalResolution); 

     //make a graphics object from the empty bitmap 
     Graphics g = Graphics.FromImage(bmpRet); 

     //Put the rotation point in the "center" of the image 
     g.TranslateTransform(rotateAtX + X, rotateAtY + Y); 

     //rotate the image 
     g.RotateTransform(angle); 

     //move the image back 
     g.TranslateTransform(-rotateAtX - X, -rotateAtY - Y); 

     //draw passed in image onto graphics object 
     g.DrawImage(image, new PointF(0 + X, 0 + Y)); 

     return bmpRet; 
    } 
+0

Se pourrait-il que probablement vous devez réassigner le bitmap renvoyé à la propriété pictureBox1.Image pour voir les modifications? –

+0

Cela pourrait être le problème, je fais pictureBox1.Image = bmpRet; dans la méthode mais il dit qu'il a un problème avec la référence de l'objet – user1197993

+0

nevermind, je l'ai réparé merci! – user1197993

Répondre

0

Je pense que vous devriez annuler et peindre en vous OnPaint ou un événement OnDraw

private void timer_Elapsed(object sender, EventArgs e) 
{ 
    //Graphics graphic = Graphics.FromImage(pictureBox1.Image); 
    //graphic.RotateTransform(45); 


    // this.Invoke(new MethodInvoker(delegate { RotateImage(pictureBox1.Image, 10); }));  

    pictureBox1.Invalidate(); 
} 

Dans votre formulaire, vous devez activer ces styles pour une meilleure perfomance et la douceur

SetStyle(ControlStyles.ResizeRedraw, true); 
SetStyle(ControlStyles.UserPaint, true); 
SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);    
+0

Merci, cela a aidé. Mais je ne peux pas croire que j'ai oublié de réaffecter l'image bitmap renvoyée à l'image de la boîte d'image! – user1197993