【WPF學習】第五十二章 動畫性能

来源:https://www.cnblogs.com/Peter-Luo/archive/2020/03/01/12392957.html
-Advertisement-
Play Games

通常,為用戶界面應用動畫只不過是創建並配置正確的動畫和故事板對象。但在其他情況下,特別是同時發生多個動畫時,可能需要更加關註性能。特定的效果更可能導致這些問題——例如,那些涉及視頻、大點陣圖以及多層透明等的效果通常需要占用更多CPU開銷。如果不謹慎實現這類效果,運行它們使可能造成明顯抖動,或者會從其他 ...


  通常,為用戶界面應用動畫只不過是創建並配置正確的動畫和故事板對象。但在其他情況下,特別是同時發生多個動畫時,可能需要更加關註性能。特定的效果更可能導致這些問題——例如,那些涉及視頻、大點陣圖以及多層透明等的效果通常需要占用更多CPU開銷。如果不謹慎實現這類效果,運行它們使可能造成明顯抖動,或者會從其他同時運行的應用程式搶占CPU時間。

  幸運的是,WPF提供了幾個可提供幫助的技巧。接下來的幾節將學習降低最大幀率以及緩存電腦顯卡中的點陣圖,這兩種技術可以減輕CPU的負擔。

一、期望的幀率

  正如前面所學習的,WPF試圖保持以60幀/秒的速度運動動畫。這樣可確保從開始到結束得到平滑流暢的動畫。當然,WPF可能達不到這個目標。如果同時運行多個複雜的動畫,並且CPU或顯卡不能承受的話,整個幀率可能會下降(最好的情形),甚至可能會跳躍以進行補償(最壞的情形)。

  儘管很少提高幀率,但可能會選擇降低幀率,這可能是因為以下兩個原因之一:

  •   動畫使用更低的幀率看起來也很好,所以不希望浪費額外的CPU周期。
  •   應用程式運行在性能較差的CPU或顯卡上,並知道使用高的幀率時整個動畫的渲染效果還不如使用更低的幀率的渲染效果好。

  調整幀率很容易。只需要為包含動畫的故事板使用Timeline.DesiredFrameRate附加屬性。下麵的示例將幀率減半:

<Storyboard Timeline.DesiredFrameRate="30">

  下圖顯示了一個簡單的測試程式,該程式為一個小球應用動畫,使其在Canvas控制項上沿一條曲線運動。

  這個應用程式開始在Canvas上繪製Ellipse對象。Canvas.ClipToBounds屬性被設置為true,所以圓的邊緣不會超出Canvas控制項的邊緣而進入視窗的其他部分。

<Canvas ClipToBounds="True">
     <Ellipse Name="ellipse" Fill="Red" Width="10" Height="10"></Ellipse>
</Canvas>

  為在Canvas控制項上移動圓,需要同時進行兩個動畫——一個動畫用於更新Canva.Left屬性(從左向右移動圓),另一個動畫用於改變Canvas.Top屬性(使圓上升,然後下降)。Canvas.Top動畫是可反轉的——一旦圓達到最高點,就會下降。Canvas.Left動畫不是可反轉的,但持續時間是Canvas.Top動畫的兩倍,從而使得這兩個動畫可以同時移動圓。最後的技巧是為Canvas.Top動畫使用DeceleartionRatio屬性。這樣,當圓達到最高點是上升的速度會更慢,這會創建更逼真的效果。

  下麵是動畫的完整標記:

<Window.Resources>
        <BeginStoryboard x:Key="beginStoryboard">
            <Storyboard Timeline.DesiredFrameRate="{Binding ElementName=txtFrameRate,Path=Text}">
                <DoubleAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Canvas.Left)"
                         From="0" To="300" Duration="0:0:5">
                </DoubleAnimation>
                <DoubleAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Canvas.Top)"
                         From="300" To="0" AutoReverse="True" Duration="0:0:2.5"
                         DecelerationRatio="1">
                </DoubleAnimation>
            </Storyboard>
        </BeginStoryboard>
    </Window.Resources>

 這個示例的真正目的是嘗試不同的幀率。為查看某個特定幀率的效果,只需要在文本框中輸入合適的數值,然後單擊Repeat按鈕即可。然後動畫就會使用新的幀率(通過數據綁定表達式獲取新的幀率)觸發,從而可以觀察動畫的效果。在更低的幀率下,橢圓不會均勻移動——而會在Cavans控制項中的跳躍。

  也可使用代碼調整Timeline.DesiredFrame屬性。例如,可能希望讀取靜態屬性RenderCapability.Tier以確定顯卡支持的渲染級別。

二、點陣圖緩存

  點陣圖緩存通知WPF獲取內容的當前點陣圖圖像,並將其複製到顯卡的記憶體中。這時,顯卡可以控制點陣圖的操作和顯示的刷新。這個處理過程比讓WPF完成所有工作要快很多,並且和顯卡不斷通信。

  如果運用得當,點陣圖緩存可以改善應用程式的繪圖性能。但如果運用不當,就會浪費顯存並且實際上會降低性能。所以,在使用點陣圖緩存之前,需要確保真正合適。下麵列出一些指導原則:

  •   如果正在繪製的內容需要頻繁地重新繪製,使用點陣圖緩存可能是合理的。因為每次後續的重新繪製將更快。一個例子是當其他一些具有動畫的對象浮動在形狀錶面上時,使用BitmapCacheBrush畫刷繪製形狀的錶面。儘管形狀沒有變化,但是形狀的不同部分被遮擋住或顯露出來,從而需要重新繪製。
  •   如果元素的內容經常變化,使用點陣圖緩存可能不合理。因為可視化內容每次改變時,WPF需要重新渲染點陣圖將其發送到顯卡緩存,而這需要耗費時間。該規則有些晦澀,因為某些改變不會導致緩存無效。安全操作的例子包括使用變換旋轉以及重新縮放元素、剪裁元素、改變元素的透明度以及應用效果。另一方面,改變元素的內容、佈局以及各式將強制重新渲染點陣圖。
  •   儘量少緩存內容。點陣圖越大,WPF存儲緩存副本所需的時間越長,需要的顯存越多。一旦耗盡顯存,WPF將被迫使用更慢的軟體渲染。

  為更好地理解點陣圖緩存,使用一個簡單示例是有幫助的,下圖例舉一個示例,一個動畫推動一個簡單的圖像——正方形——在Canvas面板上移動,Canvas面板包含一條具有複雜集合圖形的路徑。但正方形在Canvas面板錶面上移動時,強制WPF重新計算路徑並填充丟失的部分。這會帶來極大的CPU負擔,並且動畫甚至可能開始變得斷斷續續。

 

   可採用幾種方法解決該問題。一種選擇是使用一幅點陣圖替換背景,WPF能夠更高效地管理點陣圖。更靈活的選擇是使用點陣圖緩存,這種方法可繼續將存活的、可交互的元素作為背景。

  為啟用點陣圖緩存功能,將相應元素的CacheMode屬性設置為BitmapCache。每個元素都提供了CacheMode屬性,這意味著可以精確選擇為哪個元素使用這一特征。

<Path CacheMode="BitmapCache" ...></Path>

  通過這個簡單修改,可立即看到區別。首先,視窗顯示的事件要稍長一些。但動畫的運行將更平滑,並且CPU的負擔將顯著降低。可通過Windows任務管理器進行檢查——經常可以看到CPU的負擔從接近100%減少到20%一下。

  通常,當啟用點陣圖緩存時,WPF採用元素當前尺寸的快照並將其點陣圖複製到顯卡中。如果之後使用ScaleTransform放大元素,這會變成一個問題。在這種情況下,將放大緩存的點陣圖,而不是實際的元素,當放大元素時這會導致模糊放大以及色塊。

  例如,設想一個修訂過的示例。在這個示例中,第二個同步動畫擴展Path使其為原始尺寸的10倍,然後縮回原始尺寸。為確保具有良好的顯示質量,可使用5倍於Path原始尺寸的尺寸緩存其點陣圖:

<Path ...>
    <Path.CacheMode>
        <BitmapCache RenderAtScale="5"></BitmapCache>
    </Path.CacheMode>
</Path>

  這樣可解決像素化問題。雖然緩存的點陣圖仍比Path的最大動畫尺寸(最大尺寸達10倍於其原始尺寸)小,但顯卡能使點陣圖的尺寸加倍,從5倍到10倍,而不會有任何明顯的縮放問題。更重要的是,這可使應用避免過多地使用顯存。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 基於JSP+Servlet開發失物招領系統開發環境: Windows操作系統開發工具:Myeclipse+Jdk+Tomcat7+MYSQL資料庫運行效果圖 源碼及原文鏈接:https://javadao.xyz/forum.php?mod=viewthread&tid=115 ...
  • 基於JSP+Servlet開發公交線上查詢(前臺+後臺):( 開發環境: Windows操作系統開發工具: Eclipse+Jdk+Tomcat+MYSQL資料庫運行效果圖 源碼及原文鏈接:https://javadao.xyz/forum.php?mod=viewthread&tid=120 ...
  • @[toc] 1. Spring註解的源碼分析 1.1 我如何開始分析源碼的? ==這一部分可以略過直接看第1.2節== 想必程式員都會經過這樣一個階段,當 已經能夠熟練運用。並且它的 也能夠用到 ,程式員就會找進階的入口,這時候就想到了去瞭解源碼。 作為Java程式員,首先想到的一定是瞭解Spri ...
  • React非常快速是因為它從不直接操作DOM。 虛擬DOM是在DOM的基礎上建立了一個抽象層,對數據和狀態所做的任何改動,都會被自動且高效的同步到虛擬DOM,最後再批量同步到DOM中。 在React中,render執行的結果得到的並不是真正的DOM節點,而僅僅是JavaScript對象,稱之為虛擬D ...
  • 教程共分為五篇,從AOP實例的構建及其重要組件、基本運行流程、容器創建流程、關鍵方法調用、原理總結歸納等幾個方面一步步走進AOP的世界。 本篇主要為讀者演示構建AOP實例及AOP核心組件分析。 一、項目構建 讀者可直接下載示例工程,或複製以下的代碼到本地工程開啟教程。 <?xml version=" ...
  • 學生成績管理系統 tips : 應該寫的註釋都寫了,適合初學者參考。某班最多不超過30人(具體人數由鍵盤輸入),考試科目最多不超過6門(具體門數由鍵盤輸入)。 請編寫一個程式實現如下菜單驅動的學生成績管理系統;要求:(1)錄入每個學生 的學號、姓名和各科考試成績。(2)計算每門課程的總分和平均分。( ...
  • 題目內容: 解題思路 方法一: 這是我自己摸索出來的一種方法,通過對數組的多次逆置來達到迴圈的效果,一共對數組進行了三次逆置,所以就需要構造一個函數, 這個函數既可以逆置一個數組,也可以逆置數組的部分區間。 1,先將整個數組[0,N)逆置一遍; 2,將數組的前部分區間[0,M)進行逆置; 3,將數組 ...
  • Docker介紹 Docker 是應用最廣泛的開源容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中 然後發佈到任何流行的 Linux或Windows 機器上,也可以實現虛擬化。 每個容器擁有一套和宿主機完全隔離的文件系統(共用linux內核),程式在這個虛擬容器里運行,就好像在真實 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...