创建基于.NET Framework 精简版的动画控件

导读:
  摘要:学习如何创建基于 .NET Framework 精简版的动画控件。
   简介
  在最近的项目中,有一项要求是在 Microsoft? .NET Framework 精简版的 Windows? 窗体中显示动画GIF。.NET Framework 精简版的 1.0 版没有显示动画GIF 文件的功能,也不包含 .NET Framework 完整版中的 ImageAnimator 辅助类。通过 ImageAnimator 类可以为基于时间帧的图像制作动画。
  尽管可以编写 C# 代码读取 GIF86a 格式的动画GIF,但是我在程序中选择了一种更简单直观的方法来显示动画。
   创建情节
  如果您在选定的 GIF 编辑器中打开一个动画GIF,将会看到此文件是由相互衔接的多个图像(帧)组成的:
  
  
  图 1:动画帧
  这些图像以压缩格式存储,并附带有关大小、数量和帧之间的延迟时间的信息。这些信息由显示动画的程序读取。
  许多 GIF 编辑器允许您将图像帧提取到顺序排列的“故事板”中:
  
  
  图 2:故事板
  我将故事板保存在一个位图文件中,后来将此文件转换为 GIF 格式,因为此格式的文件在 .NET Framework 精简版中占用的内存较少。现在我要向您演示如何使用此图像创建基于 .NET Framework 精简版的“动画”控件。
  让我们动起来
  我们所使用的让此位图动起来的方法相当简单。它基于这样一个事实,当您在 .NET Framework 精简版中使用图像时,不必显示载入内存的整个图像。graphics.DrawImage 方法的一个重载方法将 Rectangle 对象作为参数接受。我们就用这个矩形将故事板位图中的每个图像作为帧来处理。通过移动帧矩形的位置,我们可以动态载入要在窗体中显示的位图的不同部分。
  我们向 .NET 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 方法来绘制这些帧:
  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。
  还有不少其他选项可以提供同样的功能,例如使用 System.Threading.Timer 或是创建一个单独的线程也可以达到相同的目的;但是使用 System.Windows.Forms.Timer 更简单方便。在控件的构造函数中添加以下代码:
  public AnimateCtl()
  {
  //缓存 Graphics 对象
  graphics = this.CreateGraphics();
  //实例化 Timer
  fTimer = new System.Windows.Forms.Timer();
  //与 Timer 的 Tick 事件挂钩
  fTimer.Tick += new System.EventHandler(this.timer1_Tick);
  }
  在构造函数中,我们从控件的实例中缓存 Graphics 对象并创建一个新的 Timer 实例,然后将其与 Timer 的 Tick 事件挂钩。现在已经可以插入 StartAnimation 方法,以便实际启动动画:
  public void StartAnimation(int frWidth, int DelayInterval, int LoopCount)
  {
  frameWidth = frWidth;
  //循环次数
  loopCount = LoopCount;
  //重置循环计数器
  loopCounter = 0;
  //计算 frameCount
  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
  {
  //移到下一个帧
  currentFrame++;
  }
  else
  {
  //递增 loopCounter
  loopCounter++;
  currentFrame = 0;
  }
  Draw(currentFrame);
  }
  在上面代码的 timer1_Tick 事件中,我们检查 loopCount 以跟踪已绘制的循环次数,并将其与调用 StartAnimation 方法时捕获的 loopCounter 相比较。
  演出开始!
  我们已经完成了 AnimateCtl,现在可以进行测试。第一步,必须将带有“故事板”的图像文件添加到您的项目中。可以通过将此文件变为嵌入的资源或仅通知 Visual Studio .NET 2003 将此文件作为项目的一部分进行复制来完成此任务。在 Solution Explorer(解决方案资源管理器)中的项目上单击鼠标右键,并在弹出式菜单中选择 Add Existing Item...(添加现有项...)。浏览到图像文件并确保此文件的 Build Action(生成操作)属性已被设置为 Content(内容)。
  现在,在窗体的构造函数中插入以下代码:
  public Form1()
  {
  //
  // Windows Form Designer(Windows 窗体设计器)支持所需
  //
  InitializeComponent();
  //实例化控件
  animCtl = new AnimateCtl();
  //从图像文件指定 Bitmap
  animCtl.Bitmap = new Bitmap(@"/Program
  Files/AnimateControl/guestbk.gif");
  //设置位置
  animCtl.Location = new Point(50, 50);
  //将控件添加到窗体
  this.Controls.Add(animCtl);
  }
  在上面的代码中,我们使用从图像文件中创建的 Bitmap 对象指定动画控件的 Bitmap 属性。
  在设计器的窗体上放置两个按钮,并将以下代码添加到它们的 Click 事件中:
  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();
  }
  运行项目并点击 Start Animation(启动动画)按钮,您就可以看到动画了:
  
  
  图 3:最终产品
  伪动画GIF 文件包含的帧的数目和帧之间的延迟时间可能会变化。当您为不同的动画调用 StartAnimation 方法时,需要调整 DelayInterval 参数。
  无论怎么说,此代码都不是最终版本。AnimateCtl 不能提供动画GIF 中包含的所有功能。例如,AnimateCtl 控件不能处理帧之间的不同延迟时间。例如,您可能希望第一帧显示的时间比其他帧显示的时间稍长一些。本文中的代码对于您来说是一个很好的起点,您可以根据需要扩展此控件。
  请记住,显示高分辨率的图形动画将加重系统资源负担。一定要注意运行此代码的某些设备的内存和资源限制。不要忘记进行全面测试,并确保应用程序既不会占用所有内存,也不会占用所有处理器时间。
   小结
  虽然 .NET Framework 精简版只是 .NET Framework 完整版的一个子集,但是开发人员仍然可以创建对最终用户更具吸引力的用户界面。通过使用 .NET Framework 精简版提供的 GIF 编辑器工具和绘图能力,开发人员可以在其智能设备项目中显示动画。

本文转自
http://www.itlove.net/Article/667/729/731/2005/20051203142055.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值