How to rotate image in picture box
Asked Answered
P

2

6

I am making a winforms application. One of the features I hope to implement is a rotating gear on the home form.

When the home form is loaded, you should hover over the picture of the gear, and it should rotate in place.

But all I have so far is the RotateFlip and that just flips the picture.

Is there a way to make the gear turn in place when the mouse is hovering over it?

The code I have so far is:

Bitmap bitmap1;
    public frmHome()
    {
        InitializeComponent();
        try
        {
            bitmap1 = (Bitmap)Bitmap.FromFile(@"gear.jpg");
            gear1.SizeMode = PictureBoxSizeMode.AutoSize;
            gear1.Image = bitmap1;
        }
        catch (System.IO.FileNotFoundException)
        {
            MessageBox.Show("There was an error." +
                "Check the path to the bitmap.");
        }
    }

    private void frmHome_Load(object sender, EventArgs e)
    {
        System.Threading.Thread.Sleep(5000);
    }

    private void frmHome_FormClosed(object sender, FormClosedEventArgs e)
    {
        Application.Exit();
    }

    private void pictureBox1_MouseHover(object sender, EventArgs e)
    {

        bitmap1.RotateFlip(RotateFlipType.Rotate180FlipY);
        gear1.Image = bitmap1;
    }

Like I said, I just want to turn the gear. I am trying to do this in a Windows Form application. Using C#. Framework 4

Phenanthrene answered 19/10, 2014 at 12:57 Comment(3)
the easiest way might be to create an animated GIF and let the picturebox do the work for youQuarterhour
It is rather simple by drawing the image (instead of setting it) and transforming the Graphics..Orpah
You might want to have a look at my example of such a thing using current, non-deprecated .Net Windows UI technology, which removes the need for stupid "owner draw" hacks and the like, and reduces this task to a mere 2-line DataBinding thing.Dewyeyed
T
9

You'll have to use Timer to create rotation of the Image. There is no built in method exists for rotation.

Create a global timer:

Timer rotationTimer;

Initialize timer in the constructor of the form and create PictureBox MouseEnter and MouseLeave events:

//initializing timer
rotationTimer = new Timer();
rotationTimer.Interval = 150;    //you can change it to handle smoothness
rotationTimer.Tick += rotationTimer_Tick;

//create pictutrebox events
pictureBox1.MouseEnter += pictureBox1_MouseEnter;
pictureBox1.MouseLeave += pictureBox1_MouseLeave;

Then create their Event Handlers:

void rotationTimer_Tick(object sender, EventArgs e)
{
    Image flipImage = pictureBox1.Image;
    flipImage.RotateFlip(RotateFlipType.Rotate90FlipXY);
    pictureBox1.Image = flipImage;
}

private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
    rotationTimer.Start();
}

private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
    rotationTimer.Stop();
}
Tit answered 19/10, 2014 at 14:30 Comment(0)
O
7

You can use the Graphics.RotateTransform method like this; I use a doublebuffered Panel, a Timer and two class variables..

Bitmap bmp;
float angle = 0f;

private void Form1_Load(object sender, EventArgs e)
{
    bmp = new Bitmap(yourGrarImage);
    int dpi = 96;
    using (Graphics G = this.CreateGraphics()) dpi = (int)G.DpiX;
    bmp.SetResolution(dpi, dpi);
    panel1.ClientSize = bmp.Size;
}

private void timer1_Tick(object sender, EventArgs e)
{

    angle+=2;              // set the speed here..
    angle = angle % 360;
    panel2.Invalidate();
}


private void panel1_Paint(object sender, PaintEventArgs e)
{
    if (bmp!= null) 
    {
            float bw2 = bmp.Width / 2f;    // really ought..
            float bh2 = bmp.Height / 2f;   // to be equal!!!
            e.Graphics.TranslateTransform(bw2, bh2);
            e.Graphics.RotateTransform(angle);
            e.Graphics.TranslateTransform(-bw2, -bh2);
            e.Graphics.DrawImage(bmp, 0, 0);  
            e.Graphics.ResetTransform();
    }
}

private void panel1_MouseLeave(object sender, EventArgs e)
{
    timer1.Stop();
}

private void panel1_MouseHover(object sender, EventArgs e)
{
    timer1.Start();
    timer1.Interval = 10;    // ..and/or here
}

Make sure the image is square and has the gear in the middle!! Here is a nice one:

enter image description hereenter image description heregear with 15 cogs

Here is a flickerfree doublebuffered Panel:

public class Display : Panel
{
   public Display()
   {
      this.DoubleBuffered = true;
   }
}

Update: Instead of a Panel, which is a Container control and not really meant to draw onto you can use a Picturebox or a Label (with Autosize=false); both have the DoubleBuffered property turned on out of the box and support drawing better than Panels do.

Orpah answered 19/10, 2014 at 20:31 Comment(2)
good answer also. thanks for the pics. i struggle to find ones on the web, that i likePhenanthrene
Good luck. Since you are using Shaharyar's solution, which doesn't really rotate but simply flips by 90°, you'll have to search for a gear that looks good with these large increments..The above images have a 60° symmetry (actually broken a little by a pattern overlay.) These don't look good when being flipped.. The number of cogs should be divisible by 3 but not by 2 or 4. I add one with 15 cogs..Orpah

© 2022 - 2024 — McMap. All rights reserved.