Как повернуть изображение в графическом блоке

Я делаю приложение winforms. Одна из функций, которую я надеюсь реализовать, - это вращающаяся шестерня на домашней форме.

Когда домашняя форма загружена, вы должны навести указатель мыши на изображение шестеренки, и она должна вращаться на месте.

Но все, что у меня есть, это RotateFlip, который просто переворачивает картину.

Есть ли способ заставить шестеренку вращаться на месте при наведении на нее мыши?

Код, который у меня есть до сих пор:

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

Как я уже сказал, я просто хочу включить передачу. Я пытаюсь сделать это в приложении Windows Form. Используя C #. Рамка 4


person Nicholas Aysen    schedule 19.10.2014    source источник
comment
Самый простой способ - создать анимированный GIF и позволить окну с картинками делать всю работу за вас.   -  person Ňɏssa Pøngjǣrdenlarp    schedule 19.10.2014
comment
Это довольно просто, нарисовав изображение (вместо того, чтобы устанавливать его) и преобразовать графику.   -  person TaW    schedule 19.10.2014
comment
Возможно, вы захотите взглянуть на мой пример такой вещи с использованием текущей, не устаревшей технологии пользовательского интерфейса .Net Windows, который устраняет необходимость в глупых взломах рисования владельцем и тому подобном и сводит эту задачу к простой двухстрочной привязке данных.   -  person Federico Berasategui    schedule 20.10.2014


Ответы (2)


Вам нужно будет использовать Timer, чтобы создать поворот Image. Встроенного метода вращения не существует.

Создайте глобальный таймер:

Timer rotationTimer;

Инициализируем таймер в конструкторе формы и создаем события PictureBox MouseEnter и MouseLeave:

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

Затем создайте свои 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();
}
person Shaharyar    schedule 19.10.2014

Вы можете использовать метод Graphics.RotateTransform следующим образом; Я использую панель с двойной буферизацией, таймер и две переменные класса.

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
}

Убедитесь, что изображение квадратное и шестеренка находится посередине !! Вот хороший вариант:

введите описание изображения здесь введите описание изображения здесь  шестерня с 15 зубьями

Вот немерцающая панель с двойной буферизацией:

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

Обновление: вместо Panel, который является Container элементом управления и на самом деле не предназначен для рисования, вы можете использовать Picturebox или LabelAutosize=false); у обоих свойство DoubleBuffered включено "из коробки", и они поддерживают рисование лучше, чем Panels.

person TaW    schedule 19.10.2014
comment
тоже хороший ответ. спасибо за картинки. я изо всех сил пытаюсь найти в Интернете те, которые мне нравятся - person Nicholas Aysen; 20.10.2014
comment
Удачи. Поскольку вы используете решение Shaharyar, которое на самом деле не вращается, а просто переворачивается на 90 °, вам придется искать шестеренку, которая хорошо смотрится с такими большими приращениями ... Приведенные выше изображения имеют симметрию 60 ° (на самом деле нарушена немного наложением узора.) Они не выглядят хорошо при переворачивании .. Количество зубцов должно делиться на 3, но не на 2 или 4. Я добавляю один с 15 зубцами .. - person TaW; 20.10.2014