2 votes

Image.RotateFlip ne semble pas faire pivoter le Bitmap

J'ai trois PictureBox avec les images d'un Gear (image dans le post).
Lorsque je les survole, elles tournent. J'utilise System.Drawing.Image.RotateFlip(RotateFlipType) .
Il semble que seul le centre de l'engrenage tourne, alors que les bords sont statiques.

Image of a Gear

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

private void rotationTimer2_Tick(object sender, EventArgs e)
{
    Image flipImage = pictureBox2.Image;
    flipImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
    pictureBox2.Image = flipImage;
}

private void rotationTimer3_Tick(object sender, EventArgs e)
{
    Image flipImage = pictureBox3.Image;
    flipImage.RotateFlip(RotateFlipType.Rotate270FlipXY);
    pictureBox3.Image = flipImage;
}

private void pictureBox1_MouseHover(object sender, EventArgs e)
{
    rotationTimer.Start();
    rotationTimer2.Start();
    rotationTimer3.Start();
} //etc...

2voto

Jimi Points 4983

Voici un exemple d'image en rotation utilisant la fonction Matrix.RotateAt() méthode.
Il s'agit d'un processus assez simple :

  • Créez un objet Bitmap à partir d'un fichier image (ou d'une ressource du projet) ; notez que le Bitmap est [Cloné][2] : de cette façon, nous le détachons du FileStream (GDI+ ne verrouillera pas le fichier en cours d'utilisation). N'oubliez pas de Dispose() lorsque vous avez terminé (ou que l'application se ferme)
  • définir un angle de rotation adapté à la forme de l'image
  • définir un intervalle de temps qui génère la vitesse de rotation (combinée à l'angle de rotation). Nous utilisons un System.Windows.Form.Timer bien sûr : nous voulons qu'il tique dans le thread de l'interface utilisateur (notez que cet objet doit être Éliminé , aussi)
  • lorsque la minuterie fait tic-tac, Invalider() el toile (un contrôle PictureBox, ici)
  • utiliser Matrix.RotateAt(gearCurrentRotationAngle, [ImageCentre]) et appliquer la Matrice à la transformation du monde géométrique graphique à l'aide de sa fonction Transformer propriété
  • ajoute l'angle de rotation choisi à l'angle de rotation actuel à chaque rotation. Lorsqu'il atteint 360 degrés, il est réinitialisé à la valeur minimale (le paramètre gearRotationAngle valeur du champ, ici)

Quelques autres exemples ici :
Barres de progression circulaires transparentes se chevauchant
Classes GraphicsPath et Matrix

Rotation Matrix


using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

Bitmap gear = null;
RectangleF gearRect = Rectangle.Empty;
int gearRotateSpeed = 100;
int gearRotationAngle = 24;
int gearCurrentRotationAngle = 0;

System.Windows.Forms.Timer gearTimer = new System.Windows.Forms.Timer();

public Form1() {
    InitializeComponent();
    gear = Image.FromStream(new MemoryStream(File.ReadAllBytes(@"File Path")));

    // Assuming the Gear Image is square shaped and the PictureBox size remains constant
    // otherwise, recalculate in the Control.Resize event
    var gearScale = Math.Min(pictureBox1.Width, pictureBox1.Height) / (float)Gear.Width;
    var gearSize = new SizeF(gear.Width * gearScale, gear.Height * gearScale);
    gearRect = new RectangleF(new PointF((pictureBox1.Width - gearSize.Width) / 2.0f, (pictureBox1.Height - gearSize.Height) / 2.0f), gearSize);

    gearTimer.Tick += (s, e) => {
        gearCurrentRotationAngle += gearRotationAngle;
        if (gearCurrentRotationAngle > 360) gearCurrentRotationAngle = gearRotationAngle;
        pictureBox1.Invalidate();
    }
}

private void pictureBox1_MouseEnter(object sender, EventArgs e) {
    gearTimer.Interval = gearRotateSpeed;
    gearTimer.Start();
}

private void pictureBox1_MouseLeave(object sender, EventArgs e) => gearTimer.Stop();

private void pictureBox1_Paint(object sender, PaintEventArgs e) {
    var canvas = sender as PictureBox;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;

    PointF centerImage = new PointF(canvas.Width / 2, canvas.Height / 2);
    using (var mx = new Matrix()) {
        mx.RotateAt(gearCurrentRotationAngle, centerImage);
        e.Graphics.Transform = mx;
        e.Graphics.DrawImage(gear, gearRect);
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X