忆龙2009:在Microsoft .NET Compact Framework上实现动画效果
Posted on 2010-01-17 21:51 忆龙2009 阅读(443) 评论(1) 编辑 收藏 举报介绍
在最近的一个项目中,有一个需求是在Microsoft® .NET Compact Framework Windows® 表单上实现GIF文件的动画效果。而 .NET Compact Framework V1.0并没有提供这样的功能。这样的功能只在 .NET Framework 上支持,ImageAnimator 类允许对有时间线的动画影像进行显示。
当然,我们也可以提供用 C# 代码来读取格式为GIF86a的动画GIF,我还是选择了另外一中更加简单及直接的方法来实现。
创建故事线
如果你提供GIF编辑器来打开一个动画GIF文件,你会看到类似下图的动画帧效果:
这些图像用压缩的方式保存,而且携带有尺寸、质量、帧间延时等信息。这些信息能够被显示动画的程序所读取。
很多GIF编辑器允许你将这些图像导出成故事线:
我把这些故事线保存成一个单独的位图文件,后面我会将其装换成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();
}
当运行这个项目时我们将看到类似下面的效果: