导航

忆龙2009:在Microsoft .NET Compact Framework上实现动画效果

Posted on 2010-01-17 21:51  忆龙2009  阅读(445)  评论(1编辑  收藏  举报

介绍

在最近的一个项目中,有一个需求是在Microsoft® .NET Compact Framework Windows® 表单上实现GIF文件的动画效果。而 .NET Compact Framework V1.0并没有提供这样的功能。这样的功能只在 .NET Framework 上支持,ImageAnimator 类允许对有时间线的动画影像进行显示。

当然,我们也可以提供用 C# 代码来读取格式为GIF86a的动画GIF,我还是选择了另外一中更加简单及直接的方法来实现。

 

创建故事线

如果你提供GIF编辑器来打开一个动画GIF文件,你会看到类似下图的动画帧效果:

wps_clip_image-1932

这些图像用压缩的方式保存,而且携带有尺寸、质量、帧间延时等信息。这些信息能够被显示动画的程序所读取。

很多GIF编辑器允许你将这些图像导出成故事线:

wps_clip_image-2357

我把这些故事线保存成一个单独的位图文件,后面我会将其装换成GIF格式的文件,这样可以占用少一点的内存。下面我将介绍如何提供创建一个基于.NET Compact Framework的动画控件 Animationcontrol。

 

我们将采用的方法非常简单。

我们想一个 .NET Compact Framework 项目中添加AnimateCtl类,这个类从System.Windows.Forms.Control继承:

using System;

using System.Windows.Forms;

using System.Drawing;

using System.Drawing.Imaging;

public class AnimateCtl : System.Windows.Forms.Control

{

   // 在这添加类的实现

}

给类添加一个公有的 Bitmap 属性,它将用来从客户端获取位图:

private Bitmap bitmap;

public Bitmap Bitmap

{

   get

   {

return bitmap;

   }

   set

   {

      bitmap = value;

   {

{

这个控件用Graphics对象的DrawImage方法来创建一个 draw 方法:

private void Draw(int iframe)

{

      //计算剩下的位图帧

      int XLocation = iframe * frameWidth;

      Rectangle rect = new Rectangle(XLocation, 0, frameWidth,

        frameHeight);

      //画图

      graphics.DrawImage(bitmap, 0, 0, rect, GraphicsUnit.Pixel);

}

这个方法接受当前需要画图的帧号。我们据此计算出剩下的位图帧,然后画出一个方块。

我使用了System.Windows.Forms.Timer来控制循环逻辑。

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

}

在构造函数中我们对Graphics对象进行了缓存,并创建了一个新的定时器实例。同时挂接好定时器事件。

public void StartAnimation(int frWidth, int DelayInterval, int LoopCount)

{

      frameWidth = frWidth;

      //循环次数

      loopCount = LoopCount;

      //复位计时器

      loopCounter = 0;

      //计算帧号

      frameCount = bitmap.Width / frameWidth;

      frameHeight = bitmap.Height;

      //设置控件的尺寸

      this.Size(frameWidth, frameHeight);

      //设置延时

      fTimer.Interval = DelayInterval;

      //启动定时器

      fTimer.Enabled = true;

}

以下是循环控制逻辑:

private void timer1_Tick(object sender, System.EventArgs e)

{

         if (loopCount == -1) //一直循环

         {

            this.DrawFrame();

         }

         else

         {

            if (loopCount == loopCounter) //停止

               fTimer.Enabled = false;  

            else

               this.DrawFrame();

         }

}

private void DrawFrame()

{

      if (currentFrame < frameCount-1)

      {

         //移动到下一帧

         currentFrame++;

      }

      else

      {

         //增加计数

         loopCounter++;

         currentFrame = 0;

      }

      Draw(currentFrame);

}

在Form's构造函数中加入以下代码:

public Form1()

{

      InitializeComponent();

      //初始化一个实例

      animCtl = new AnimateCtl();

      //加载位图文件

      animCtl.Bitmap = new Bitmap(@"\Program

        Files\AnimateControl\guestbk.gif");

      //设置位置

      animCtl.Location = new Point(50, 50);

      //将控件添加到FORM

      this.Controls.Add(animCtl);

}

private void button1_Click(object sender, System.EventArgs e)

{

      animCtl.StartAnimation(92, 100, 3);

}

private void button2_Click(object sender, System.EventArgs e)

{

      animCtl.StopAnimation();

}

当运行这个项目时我们将看到类似下面的效果:

wps_clip_image-9125