簡體   English   中英

c#winforms如何旋轉圖像(但不是圍繞其中心)

[英]c# winforms how to rotate an image (but not around its center)

我正在嘗試開發一個我幾乎完成的節拍器應用程序。

我留下的唯一部分是輔助視覺,要求我及時向后和向前旋轉手臂的圖像(在時鍾上思考分針)。

如何旋轉圖像並不繞其中心點旋轉圖像。 在我寫的場景中,我需要能夠圍繞底部邊框中間的一個點旋轉圖像。

此外,我希望能夠在n毫秒內將圖像從X旋轉到Y,並使其在動畫中輕松進出。 對於C#來說,這是一座過於遙遠的橋梁嗎?是否有任何庫可以幫助我實現這種先進的物理動畫類型。

非常感謝

不是你要求的,但是:

您應該考慮翻轉一組靜態圖像,而不是每秒多次執行處理器密集型操作。

擴大回復

沒有任何閃爍 ctor中的SetStyle會處理這個問題。 你所看到的“閃爍”是由三個因素造成的神器:

  1. 更新率僅為10 /秒。 嘗試將其增加到20或30。
  2. 方向值是路線。 它應該基於時間/加速。 這是一個留給你的練習。
  3. 蹩腳的“手”圖像具有硬的鋸齒邊緣。 無論你更新的速度有多快,或者你的動畫效果如何,它都會讓人感到緊張。 再次,做反鋸齒,混合圖形處理仍然是一個練習。

仔細看一下代碼。 這不是“在表單上繪制”,它是一個自定義控件。 了解MetronomeControl如何從Control 通過添加MetronomeControl來了解我們如何創建表單?

圖片框用於顯示靜態圖像,而不是用於自定義控件!

它更新的方式是創建一個計時器。 當計時器的Tick事件觸發時,我們更新角度和方向,更一般地說,我們更新控件的狀態。 對Invalidate的調用告訴操作系統,“嘿,我需要重新繪制,在方便時向我發送WM_PAINT消息!”。 我們的OnPaint覆蓋只是繪制控件的當前狀態。

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

可能這個示例代碼很有用:

Graphics x=Graphics.FromImage(m);
x.TranslateTransform(m.Width / 2, m.Height / 2);
x.RotateTransform(30);
SizeF textSize = x.MeasureString("hi", font);
x.DrawString("hi", font, Brushes.Red, -(textSize.Width / 2), -(textSize.Height / 2);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM