Image.RotateFlip 似乎没有旋转位图

问题描述 投票:0回答:1

我有三个带有齿轮图像的 PictureBox(图片在帖子中)。
当我将鼠标悬停在它们上时,它们会旋转。我正在使用

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...
c# winforms graphics bitmap image-rotation
1个回答
2
投票

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

  • 从图像文件(或项目资源)创建位图对象。完成后记得Dispose()
  • 定义适合图像形状的旋转角度
  • 设置生成旋转速度(与旋转角度相结合)的计时器间隔。当然,我们使用的是 System.Windows.Form.Timer:我们希望它在 UI 线程中 tick(请注意,该对象也需要 Dispose
  • 当计时器滴答作响时,Invalidate()canvas(此处为 PictureBox 控件)
  • 使用
    Matrix.RotateAt(gearCurrentRotationAngle, [ImageCentre])
    并使用其 Transform 属性将 Matrix 应用于图形几何世界变换
  • 每次旋转时将所选旋转角度添加到当前旋转角度。当达到 360 度时,重新设置为最小值(此处为
    gearRotationAngle
    字段值)

这里还有一些其他例子:
透明重叠圆形进度条
GraphicsPath 和 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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.