【问题标题】:Wrong rectangle drawing with gif animation using MSDN example使用 MSDN 示例使用 gif 动画绘制错误的矩形
【发布时间】:2012-10-15 14:34:45
【问题描述】:

我有一个 gif 动画。当我在 CompactFramework 工作时,我关注了this MSDN example

基本思想是将帧添加到图像中并用下一帧重绘rectangle,从而创建动画。它工作得很好,只是动画显示在一个正方形中,而不是我的图像的全尺寸(即 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);
    }        
}

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

【问题讨论】:

    标签: c# compact-framework animated-gif rectangles


    【解决方案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() 你只能得到当前的图形大小,但在窗体显示之后控件大小可能会改变。

    【讨论】:

    • 我添加了您的代码,但它产生了相同的结果。事实上,如果我在'e.Graphics.DrawImage' 之后立即调试 OnPaint,它会绘制显示正方形的矩形。但矩形的尺寸应该是 240x320。我不明白为什么会这样。感谢您的帮助!
    • 在将控件 (animCtl) 添加到 controlcollection 后是否更改其大小? animCtl.Size = new Size(240; 320);
    • 这就是问题所在!我添加了this.Size = new Size(240,320);,现在它工作正常。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-25
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 2014-06-16
    相关资源
    最近更新 更多