Image.RotateFlip 似乎没有旋转位图 [英] Image.RotateFlip doesn't seem to rotate the Bitmap

查看:21
本文介绍了Image.RotateFlip 似乎没有旋转位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

private void rotationTimer_Tick(object sender, EventArgs e){图片flipImage = pictureBox1.Image;flipImage.RotateFlip(RotateFlipType.Rotate90FlipXY);pictureBox1.Image = flipImage;}private void rotationTimer2_Tick(object sender, EventArgs e){图像翻转图像 = pictureBox2.Image;flipImage.RotateFlip(RotateFlipType.Rotate90FlipNone);pictureBox2.Image = flipImage;}private void rotationTimer3_Tick(object sender, EventArgs e){图像翻转图像 = pictureBox3.Image;flipImage.RotateFlip(RotateFlipType.Rotate270FlipXY);pictureBox3.Image = flipImage;}private void pictureBox1_MouseHover(对象发送者,EventArgs e){rotationTimer.Start();rotationTimer2.Start();rotationTimer3.Start();}//等等...

解决方案

以下是使用


使用 System.Drawing;使用 System.Drawing.Drawing2D;使用 System.Windows.Forms;位图齿轮=空;RectangleF gearRect = Rectangle.Empty;int gearRotateSpeed = 100;int gearRotationAngle = 24;int gearCurrentRotationAngle = 0;System.Windows.Forms.Timer gearTimer = new System.Windows.Forms.Timer();公共表单1(){初始化组件();gear = Image.FromStream(new MemoryStream(File.ReadAllBytes(@"File Path")));//假设 Gear Image 为方形且 PictureBox 大小保持不变//否则,在 Control.Resize 事件中重新计算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(对象发送者,EventArgs e){gearTimer.Interval = gearRotateSpeed;gearTimer.Start();}private void pictureBox1_MouseLeave(object sender, EventArgs e) =>gearTimer.Stop();private void pictureBox1_Paint(对象发送者,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);使用 (var mx = new Matrix()) {mx.RotateAt(gearCurrentRotationAngle, centerImage);e.Graphics.Transform = mx;e.Graphics.DrawImage(gear, gearRect);}}

I have three PictureBox with the images of a Gear (picture in post).
When I hover on them, they rotate. I am using System.Drawing.Image.RotateFlip(RotateFlipType).
It looks like only the center of the gear rotates but the edges are static.

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

解决方案

Here's an example of a rotating image using the Matrix.RotateAt() method.
This is a pretty simple process:

  • Create a Bitmap object from an Image file (or a Project resource); note that the Bitmap is [Cloned][2]: this way, we are detaching it from the FileStream (GDI+ won't lock the file while in use). Remember to Dispose() of it when you're done with it (or the application closes)
  • define a rotation angle that fits the image shape
  • set a Timer interval that generates the rotation speed (combined with the rotation angle). We are using a System.Windows.Form.Timer of course: we want it to tick in the UI thread (note that this object needs to be Disposed, too)
  • when the Timer ticks, Invalidate() the canvas (a PictureBox control, here)
  • use Matrix.RotateAt(gearCurrentRotationAngle, [ImageCentre]) and apply the Matrix to the Graphics geometric world transformation using its Transform property
  • add the chosen rotation angle to the current rotation angle at each rotation. When it reaches 360 degrees, re-set to min value (the gearRotationAngle field value, here)

Some other examples here:
Transparent Overlapping Circular Progress Bars
GraphicsPath and Matrix classes


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

这篇关于Image.RotateFlip 似乎没有旋转位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆