Image.RotateFlip似乎没有旋转位图

时间:2018-12-13 13:14:12

标签: c# winforms

我有三个PictureBox,上面有一个Gear的图像(帖子中的图片)。
当我将鼠标悬停在它们上时,它们会旋转。我正在使用System.Drawing.Image.RotateFlip(RotateFlipType)
看起来只有齿轮的中心在旋转,而边缘却是静止的。

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...

1 个答案:

答案 0 :(得分:1)

下面是使用Matrix.RotateAt()方法旋转图像的示例。
这是一个非常简单的过程:

  • 从图像文件(或项目资源)创建位图对象;请注意,位图是Cloned:这样,我们就将其从FileStream中分离出来(GDI +在使用时不会锁定文件)。完成操作(或关闭应用程序)后,请记住Dispose()
  • 定义适合图像形状的旋转角度,
  • 设置一个计时器间隔,该间隔生成转速(与旋转角度结合)。当然,我们使用的是System.Windows.Form.Timer:我们希望它在UI线程中 tick (请注意,该对象也必须是Disposed
  • 当计时器计时时,Invalidate() canvas (此处为PictureBox控件)
  • 使用Matrix.RotateAt(GearCurrentRotationAngle, [ImageCentre]),并使用其Matrix属性将Transform应用于Graphics几何世界变换,
  • 在每次旋转时将选择的旋转角添加到当前旋转角。当达到360度时,将其重置为最小值(此处为GearRotationAngle字段值)

此处还有一些其他示例:
Transparent Overlapping Circular Progress Bars
GraphicsPath and Matrix classes

Rotation Matrix


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

Bitmap Gear = null;
System.Windows.Forms.Timer GearTimer = new System.Windows.Forms.Timer();
int GearRotateSpeed = 100;
int GearRotationAngle = 24;
int GearCurrentRotationAngle = 0;

public Form1() {
    InitializeComponent();
    Gear = (Bitmap)Image.FromFile(@"File Path").Clone();
    GearTimer.Tick += (s, e) => { 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) {
    PictureBox pBox = sender as PictureBox;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
    PointF CenterImage = new PointF(pBox.Width / 2, pBox.Height / 2);

    using (Matrix matrix = new Matrix()) {
        matrix.RotateAt(GearCurrentRotationAngle, CenterImage);
        e.Graphics.Transform = matrix;
        e.Graphics.DrawImage(Gear, pBox.ClientRectangle, new Rectangle(Point.Empty, Gear.Size), GraphicsUnit.Pixel);
    }
    GearCurrentRotationAngle += GearRotationAngle;
    if (GearCurrentRotationAngle > 360) GearCurrentRotationAngle = GearRotationAngle;
}