NGif是.net 中用來創建gif圖片的類庫,可以遷移到windows phone中來,在windows phone中創建gif圖片。
Gif動畫就是在一定時間間隔內,將圖片依次顯示,將多幅圖像保存為一個圖像文件,從而形成動畫。
把NGif遷移到windows phone有兩種不同的方式
1. 在原始的NGif中采用image對象表示當前幀的圖像,windows phone中也有image對象,直接使用,只要修改部分不兼容的代碼即可
2. 使用WriteableBitmap代替image,用來表示當前幀的圖像。
在文字末尾的示例demo中兩種方式都有源代碼提供。
方式一:
在NGif中,使用了GDI技術,我們可以使用WriteableBitmap的擴展方法去替換。
Image temp = new Bitmap(width, height); Graphics g = Graphics.FromImage(temp); g.DrawImage(image, 0, 0); image = temp; g.Dispose();
可以寫為
WriteableBitmap temp = new WriteableBitmap(image,null); temp.Resize(width, height, WriteableBitmapExtensions.Interpolation.NearestNeighbor); image = new Image { Source = temp };
至於其他的遷移代碼可以在源代碼中查看。
本文將會使用遷移后的NGif從相冊中選擇圖片,制作GIF圖片以及最后在程序中顯示制作的圖片。首頁運行效果如下:
圖片選擇的模板如下:
<DataTemplate x:Key="DT_Image"> <Grid> <Button Click="Button_Click"> <Button.Template> <ControlTemplate> <Image Source="{Binding Thumbnail}" Height="100" Width="100" Margin="5" /> </ControlTemplate> </Button.Template> </Button> <Image Source="selected.png" Height="32" Width="32" Visibility="{Binding IsSelectedVisibility}" HorizontalAlignment="Right" VerticalAlignment="Bottom"/> </Grid> </DataTemplate>
ListBox代碼如下:
<ListBox x:Name="lbDefault" Margin="7,-10,0,0" ItemTemplate="{StaticResource DT_Image}" ItemsSource="{Binding DefaultImages}"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <toolkit:WrapPanel/> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox>
至於從相冊中加載圖片可以查看程序源代碼。
看一下制作GIF的代碼
private void btn2_Click(object sender, RoutedEventArgs e) { List<PhotoCell> list = new List<PhotoCell>(); foreach (var item in defaultImages) { if (item.IsSelectedVisibility == System.Windows.Visibility.Visible) { list.Add(item); } } if (list.Count == 0) { MessageBox.Show("請選擇圖片"); return; } String outputFilePath = "test2.gif"; GifLib2.AnimatedGifEncoder maker = new GifLib2.AnimatedGifEncoder(); maker.Start(outputFilePath); maker.SetDelay(500); //-1:no repeat,0:always repeat maker.SetRepeat(0); foreach (var item in list) { maker.AddFrame(item.Image.Resize(320, 320, WriteableBitmapExtensions.Interpolation.NearestNeighbor)); } maker.Finish(); MessageBox.Show("done, find it in iso named :" + outputFilePath); NavigationService.Navigate(new Uri("/DisplayGifPage.xaml?name=" + outputFilePath, UriKind.Relative)); }
首先實例化AnimatedGifEncoder對象,設置其輸出路徑,間隔時間,以及重復次數,然后將要制作的圖片添加到其幀中就可以了。
制作Gif完成后,我們會在程序中顯示制作的Gif,此時就要用到GifDecoder了,將Gif解碼為一張張圖片。
private void LoadGif(string name) { GifDecoder decoder = new GifDecoder(); using (var store = IsolatedStorageFile.GetUserStoreForApplication()) { if (!store.FileExists(name)) { MessageBox.Show("gif image 不存在"); return; } using (var stream = store.OpenFile(name, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { decoder.Read(stream); //get frame size to set image size Size size = decoder.GetFrameSize(); image.Width = size.Width; image.Height = size.Height; int delay = decoder.GetDelay(1); //0 stand for loop forever, otherwise is the real count int loopCount = decoder.GetLoopCount(); //decoder.GetLoopCount int imagecount = decoder.GetFrameCount(); for (int i = 0; i < imagecount; i++) { imageList.Add(decoder.GetFrame(i)); } DisplayGif(delay, loopCount); } } }
從獨立存儲空間中加載Gif,並且獲取他的一些屬性:重復次數,幀數,以及每一幀對應的圖像,然后使用一個Timer將其顯示即可:
private void DisplayGif(int delay, int loopCount) { DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromMilliseconds(delay); int index = 0; int loopedCount = 0;//已經循環的次數 timer.Tick += (sender, e) => { //如果是永遠循環 if (loopCount == 0) { if (index == imageList.Count - 1) { index = 0; } } else { if (loopCount == loopedCount) { timer.Stop(); } loopedCount++; } image.Source = imageList[index]; index++; }; timer.Start(); }
本文僅僅講述了如何在windows phone中制作Gif,並且解碼並顯示Gif,其中很多代碼可以優化,大家可以酌情使用本示例中的代碼。
源代碼可以在這里找到。

