天天看點

建立基于 Microsoft .NET Framework 精簡版的動畫控件 - Chep

建立基于 Microsoft .NET Framework 精簡版的動畫控件

引自:http://www.microsoft.com/china/msdn/archives/library/dnnetcomp/html/animationcontrol.asp

Alex Yakhnin

IntelliProg, Inc.

2003年3月

适用于:

    Microsoft® .NET Framework 精簡版

    Microsoft Visual Studio® .NET 2003

    Microsoft Windows® CE .NET

摘要:

學習如何建立基于 .NET Framework 精簡版的動畫控件。

下載下傳 AnimationControl.msi(英文)。(請注意,在示例檔案中,程式員的注釋使用的是英文,本文中将其譯為中文是為了便于讀者了解。)

目錄

  • 簡介
  • 建立情節
  • 讓我們動起來
  • 演出開始!
  • 小結

簡介

在最近的項目中,有一項要求是在 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 < frameCount-1)
      {
         //移到下一個幀
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 編輯器工具和繪圖能力,開發人員可以在其智能裝置項目中顯示動畫。

建立基于 Microsoft .NET Framework 精簡版的動畫控件 - Chep