C#的WinForms如何旋转图像(但不是围绕其中心) [英] c# winforms how to rotate an image (but not around its center)

查看:119
本文介绍了C#的WinForms如何旋转图像(但不是围绕其中心)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图开发一种我几乎完成节拍器应用程序。

I am trying to develop a metronome application which I have almost completed.

我留下的唯一的部分是次要的视觉,需要我旋转手臂的图像(认为在一个时钟分针)向后和向前的时间

The only portion I have left is a secondary visual that requires me to rotate an image of an arm (think minute hand on a clock) backwards and forwards in time.

我怎么能旋转的图像,并通过不旋转它围绕其中心点这样做。在方案中,我写我需要​​能够在其底边框的中间点周围旋转图像。

how can I rotate an image and do so by not rotating it around its center point. in the scenario I am writing for I need to be able to rotate the image around a point in the middle of its bottom border.

另外,我想能够根据X旋转图像的Y n毫秒,并让它缓解进出动画。这是一个桥太远,C#以及是否有可以帮助我实现物理动画的此类型的提前任何库。

Also, I would like to be able to rotate the image from X to Y in n milliseconds and have it ease in and out in the animation. Is this a bridge too far for C# and are there any libraries that could help me achieve this advance type of physics animation.

非常感谢

推荐答案

回复扩展

有是的无频闪任何的。在构造函数中的SetStyle需要的照顾。你看到的是忽悠,是由三个因素一个神器的原因:

There is no flicker whatsoever. The SetStyle in the ctor takes care of that. What you see as "flicker" is an artifact cause by three factors:


  1. 更新率仅为10 /秒。尝试增加,为20或30。

  2. 方向值为课程。应当基于时间/ accelleration。这是留给你的锻炼。

  3. <李>蹩脚的手的形象很难,别名边缘。无论你如何快速升级或如何平滑你制作动画,它会看起来战战兢兢。同样,做抗锯齿,混合图形处理留作练习。

看那code更仔细。这不是画的形式,这是一个自定义的控制。怎么看 MetronomeControl 派生控制?看看我们是如何创建的窗体中添加一个MetronomeControl呢?

Look at the code more carefully. This is not "painted on the form", it's a custom control. See how MetronomeControl derives from Control? See how we created the form by adding a MetronomeControl to it?

图片框是用来显示静态图像,而不是自定义控件!

它更新的方法是创建一个计时器。当计时器的Tick事件触发我们更新了角度和方向,更普遍的,我们更新了控制的状态。无效的调用告诉操作系统,嘿,我需要重新绘制,给我一个WM_PAINT消息时,它的方便!。我们的OnPaint覆盖只需绘制控件的当前状态。

The way it updates is by creating a timer. When the timer's Tick event fires we update the angle and direction, more generally, we update the state of the control. The call to Invalidate tells the Operating System, "Hey, I need to be repainted, send me a WM_PAINT message when it's convenient!". Our OnPaint override simply paints the current state of the control.

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

class MetronomeControl : Control
{
    private Bitmap hand;
    private float angle = 0;
    private float direction = 2;
    private Timer timer = new Timer { Enabled = true, Interval = 30 };

    public MetronomeControl()
    {
        SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.Opaque | ControlStyles.AllPaintingInWmPaint, true);
        hand = CreateCrappyHandBitmap();
        timer.Tick += new EventHandler(timer_Tick);
    }

    void timer_Tick(object sender, EventArgs e)
    {
        if (angle < -45 || angle > 45)
            direction = -direction;
        angle += direction;
        Invalidate();
    }

    private static Bitmap CreateCrappyHandBitmap()
    {
        Bitmap bitmap = new Bitmap(100, 300, PixelFormat.Format32bppArgb);
        using (Graphics graphics = Graphics.FromImage(bitmap))
        {
            graphics.Clear(Color.Transparent);
            graphics.FillRectangle(Brushes.LightGray, 50 - 5, 0, 10, 300);
            graphics.FillPolygon(Brushes.LightSlateGray, new Point[] { new Point(50 - 30, 40), new Point(50 + 30, 40), new Point(50 + 20, 80), new Point(50 - 20, 80) });
            graphics.FillEllipse(Brushes.LightSlateGray, 0, 200, 100, 100);
        }
        return bitmap;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // Erase background since we specified AllPaintingInWmPaint
        e.Graphics.Clear(Color.AliceBlue);

        e.Graphics.DrawString(Text, Font, Brushes.Black, new RectangleF(0, 0, ClientSize.Width, ClientSize.Height), new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });

        // Move the 0,0 point to the just below the bottom-center of our client area
        e.Graphics.TranslateTransform(ClientSize.Width / 2, ClientSize.Height + 40);
        // Rotate around this new 0,0
        e.Graphics.RotateTransform(angle);
        // Turn on AA to make it a bit less jagged looking
        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        // Draw the image so that the center of the ellipse is at 0,0
        e.Graphics.DrawImage(hand, 0 - hand.Width / 2, 0 - hand.Height + 50);

        // Reset the transform for other drawing
        e.Graphics.ResetTransform();

        base.OnPaint(e);
    }
}

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form
        {
            Text = "Metronome Control Demo",
            ClientSize = new Size(640, 480),
            Controls =
            {
                new MetronomeControl
                {
                    Location = new Point(10, 10),
                    Size = new Size (340, 300),
                    Font = new Font(FontFamily.GenericSansSerif, 24),
                    Text = "Metronome Control Demo",
                }
            }
        });
    }
}

这篇关于C#的WinForms如何旋转图像(但不是围绕其中心)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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