轉帖|其它|編輯:郝浩|2010-09-16 13:55:22.000|閱讀 543 次
概述:在最近的項目中,有一項要求是在 Microsoft .NET Framework 精簡版的 Windows 窗體中顯示動畫 GIF。.NET Framework 精簡版的 1.0 版沒有顯示動畫 GIF 文件的功能,也不包含 .NET Framework 完整版中的 ImageAnimator 輔助類。通過 ImageAnimator 類可以為基于時間幀的圖像制作動畫。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
簡介
在最近的項目中,有一項要求是在 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; 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) Rectangle rect = new Rectangle(XLocation, 0, frameWidth, //繪制圖像 |
此方法接受需要繪制的當前幀號。然后計算圖形框的左邊位置以創建矩形。
為了實現該控件的循環邏輯,我選擇使用 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; |
此方法接受一些非常重要的動畫參數:幀寬度、延遲間隔和循環次數。
另外,不要忘記循環邏輯:
private void timer1_Tick(object sender, System.EventArgs e) private void DrawFrame() |
在上面代碼的 timer1_Tick 事件中,我們檢查 loopCount 以跟蹤已繪制的循環次數,并將其與調用 StartAnimation 方法時捕獲的 loopCounter 相比較。
我們已經完成了 AnimateCtl,現在可以進行測試。第一步,必須將帶有“故事板”的圖像文件添加到您的項目中??梢酝ㄟ^將此文件變為嵌入的資源或僅通知 Visual Studio .net 2003 將此文件作為項目的一部分進行復制來完成此任務。在 Solution Explorer(解決方案資源管理器)中的項目上單擊鼠標右鍵,并在彈出式菜單中選擇 Add Existing Item...(添加現有項...)。瀏覽到圖像文件并確保此文件的 Build Action(生成操作)屬性已被設置為 Content(內容)。
現在,在窗體的構造函數中插入以下代碼:
public Form1() //實例化控件 |
在上面的代碼中,我們使用從圖像文件中創建的 Bitmap 對象指定動畫控件的 Bitmap 屬性。
在設計器的窗體上放置兩個按鈕,并將以下代碼添加到它們的 Click 事件中:
private void button1_Click(object sender, System.EventArgs e)
|
運行項目并點擊 Start Animation(啟動動畫)按鈕,您就可以看到動畫了:
圖 3:最終產品
偽動畫 GIF 文件包含的幀的數目和幀之間的延遲時間可能會變化。當您為不同的動畫調用 StartAnimation 方法時,需要調整 DelayInterval 參數。
無論怎么說,此代碼都不是最終版本。AnimateCtl 不能提供動畫 GIF 中包含的所有功能。例如,AnimateCtl 控件不能處理幀之間的不同延遲時間。例如,您可能希望第一幀顯示的時間比其他幀顯示的時間稍長一些。本文中的代碼對于您來說是一個很好的起點,您可以根據需要擴展此控件。
請記住,顯示高分辨率的圖形動畫將加重系統資源負擔。一定要注意運行此代碼的某些設備的內存和資源限制。不要忘記進行全面測試,并確保應用程序既不會占用所有內存,也不會占用所有處理器時間。
小結
雖然 .NET Framework 精簡版只是 .NET Framework 完整版的一個子集,但是開發人員仍然可以創建對最終用戶更具吸引力的用戶界面。通過使用 .NET Framework 精簡版提供的 GIF 編輯器工具和繪圖能力,開發人員可以在其智能設備項目中顯示動畫。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:網絡轉載