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); } }}
從隔離儲存區 (Isolated Storage)空間中載入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,其中很多代碼可以最佳化,大家可以酌情使用本樣本中的代碼。
原始碼可以在這裡找到。