WPF 循環切換圖片達到動畫效果


  最近剛接觸WPF,  一邊學着一邊用着,知識點還沒有系統化的進行學習整理.

  現在手上有一些美術做好的圖片,需要連起來觀看形成動畫的效果,由於需求比較急,一時半會也靜不下心來看WPF關於動畫的知識.

  潛意識里一個Image控件,循環設定Source屬性,一看效果總是顯示集合的最后一項.難道是循環速度太快?基於此思路下折騰了好久也無結果。開始不得不借着可以找到的資源進行嘗試。試想我們一張張的圖片進行播放形成的動畫,是不是類似幀的這種概念.順這個便找到了CompositionTarget.Rendering事件創建基於幀的動畫.

  第一種嘗試:

 

namespace ImgAniDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ObservableCollection<BitmapImage> bmList;

        public MainWindow()
        {
            InitializeComponent();

            InitList();

            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
        }

        public void InitList()
        {
            bmList = new ObservableCollection<BitmapImage>();
            for (int i = 1; i < 4; i++)
            {
                BitmapImage bmImg = new BitmapImage(new Uri(System.Environment.CurrentDirectory + "\\" + i.ToString() + ".jpg"));
                bmList.Add(bmImg);
            }
        }

        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            for (int i = 0; i < bmList.Count; i++)
            {
                this.imgViewer.Source = bmList[i];
                this.imgViewer.Width = this.imgViewer.Source.Width;
                this.imgViewer.Height = this.imgViewer.Source.Height;
            }
        }
    }
}

 運行程序ImgAniDemo.exe結果還是只顯示了最后一幅圖片.

  回頭認真思考一下,可以做一個這樣的猜測,WPF是不是做了優化,如果循環去設置Image的Source屬性,用戶看到的效果只會是最后一張圖片呢?

  Render是什么意思?不錯,Rendering事件被處理的時候,我們是用了一個循環,按着上面的猜測,只會顯示最后一張圖片便在情理之中了.

  聰明的你一定是想到了方法,我們在Rendering事件的時候不去循環了,只指定某一個圖片給Source屬性不就ok了嗎?

  修改后的代碼:

namespace ImgAniDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ObservableCollection<BitmapImage> bmList;

int index = 0; //記錄索引

public MainWindow()
{
InitializeComponent();

InitList();

CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
}

public void InitList()
{
bmList = new ObservableCollection<BitmapImage>();
for (int i = 1; i < 4; i++)
{
BitmapImage bmImg = new BitmapImage(new Uri(System.Environment.CurrentDirectory + "\\" + i.ToString() + ".jpg"));
bmList.Add(bmImg);
}
}

void CompositionTarget_Rendering(object sender, EventArgs e)
{
if (index < bmList.Count)
{
this.imgViewer.Source = bmList[index];
this.imgViewer.Width = this.imgViewer.Source.Width;
this.imgViewer.Height = this.imgViewer.Source.Height;

index++;
}
else
{
index = 0;
}
}
}
}

這時候我們已經可以看到圖片在自動切換了.會不會感覺速度太快了,我想按着一定的速度來控件切換怎么辦?

直接上代碼了

namespace ImgAniDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ObservableCollection<BitmapImage> bmList;

int index = 0; //記錄索引
bool isRendering = false;

public MainWindow()
{
InitializeComponent();

InitList();

CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync();
}

void bw_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
isRendering = true;
System.Threading.Thread.Sleep(1000); //停1秒
}
}

public void InitList()
{
bmList = new ObservableCollection<BitmapImage>();
for (int i = 1; i < 4; i++)
{
BitmapImage bmImg = new BitmapImage(new Uri(System.Environment.CurrentDirectory + "\\" + i.ToString() + ".jpg"));
bmList.Add(bmImg);
}
}

void CompositionTarget_Rendering(object sender, EventArgs e)
{
if (isRendering)
{
if (index < bmList.Count)
{
this.imgViewer.Source = bmList[index];
this.imgViewer.Width = this.imgViewer.Source.Width;
this.imgViewer.Height = this.imgViewer.Source.Height;

index++;
}
else
{
index = 0;
}
isRendering = false;
}
}
}
}

在運行看下效果呢?

呵呵,圖片是不是在自動播放呢?

 

注:以上代碼中用到的圖片名稱分別為1.jpg,2.jpg,3.jpg,且圖片放在exe程序一起即可

 

以上僅是個人想到的一種方法,若有不正確的地方,還請多多指點...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM