1

我有一个gif动画。当我在 CompactFramework 中工作时,我遵循了这个 MSDN 示例

基本思想是将帧添加到图像中并rectangle用下一帧重绘 a,从而创建动画。它工作得很好,只是动画显示在一个正方形中,而不是我的图像的全尺寸(即 240,320)。

这是我的代码:

在 AnimateCtl.cs 类中:

public class AnimateCtl : System.Windows.Forms.Control
{
    Timer fTimer;
    int frameWidth = 240;
    int frameHeight = 320;
    int loopCount = 0;
    int loopCounter = 0;
    int frameCount;
    int currentFrame = 0;
    Graphics graphics;

    private Bitmap bitmap;
    public Bitmap Bitmap
    {
        get
        {
            return bitmap;
        }
        set
        {
            bitmap = value;
        }
    }

    private void Draw(int iframe)
    {
        //Calculate the left location of the drawing frame
        int XLocation = iframe * frameWidth;

        Rectangle rect = new Rectangle(XLocation, 0, frameWidth, frameHeight);

        //Draw image
        graphics.DrawImage(bitmap, 0, 0, rect, GraphicsUnit.Pixel);
    }

    public AnimateCtl()
    {
        //Cache the Graphics object
        graphics = this.CreateGraphics();
        //Instantiate the Timer
        fTimer = new System.Windows.Forms.Timer();
        //Hook up to the Timer's Tick event
        fTimer.Tick += new System.EventHandler(this.timer1_Tick);
    }

    /// <summary>
    /// Start animation
    /// </summary>
    /// <param name="frWidth"></param>
    /// <param name="DelayInterval"></param>
    /// <param name="LoopCount"></param>
    public void StartAnimation(int frWidth, int DelayInterval, int LoopCount)
    {

        frameWidth = frWidth;
        //How many times to loop
        loopCount = LoopCount;
        //Reset loop counter
        loopCounter = 0;
        //Calculate the frameCount
        frameCount = bitmap.Width / frameWidth;
        frameHeight = bitmap.Height;
        //Resize the control
        //this.Size(frameWidth, frameHeight);
        //Assign delay interval to the timer
        fTimer.Interval = DelayInterval;
        //Start the timer
        fTimer.Enabled = true;
    }

    private void timer1_Tick(object sender, System.EventArgs e)
    {
        if (loopCount == -1) //loop continuously
        {
            this.DrawFrame();
        }
        else
        {
            if (loopCount == loopCounter) //stop the animation
                fTimer.Enabled = false;
            else
                this.DrawFrame();
        }
    }

    private void DrawFrame()
    {
        if (currentFrame < frameCount - 1)
        {
            //move to the next frame
            currentFrame++;
        }
        else
        {
            //increment the loopCounter
            loopCounter++;
            currentFrame = 0;
        }
        Draw(currentFrame);
    }

在我的 Form1 中:

public partial class Form1 : Form
{
    AnimateCtl animCtl;

    public Form1()
    {
        InitializeComponent();

        //Instantiate control
        animCtl = new AnimateCtl();
        //Assign the Bitmap from the image file
        animCtl.Bitmap = new Bitmap(@"\Program Files\Animacion\Animacion-Frames.jpg");
        //Set the location
        animCtl.Location = new Point(0, 0);
        //Add to control to the Form
        this.Controls.Add(animCtl);

        animCtl.StartAnimation(240, 100, 3);
    }        
}

为什么它没有以正确的尺寸绘制矩形?谢谢你的帮助!

4

1 回答 1

1

删除 Draw 方法并像这样更新 DrawFrame

    private void DrawFrame() {
        if (currentFrame < frameCount - 1) {
            currentFrame++;
        } else {
            loopCounter++;
            currentFrame = 0;
        }
        this.Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e) {
        base.OnPaint(e);

        int XLocation = currentFrame * frameWidth;
        Rectangle rect = new Rectangle(XLocation, 0, frameWidth, frameHeight);
        e.Graphics.DrawImage(bitmap, 0, 0, rect, GraphicsUnit.Pixel);
    }

永远不要使用 this.CreateGraphics()。覆盖 OnPaint 方法是正确的方法。OnPaint 将始终在您调用 this.Invalidate(); 后触发。

使用 this.CreateGraphics() 您只能获得当前的图形大小,但在表单显示之后,控件大小可能会发生变化。

于 2012-10-15T15:05:20.227 回答