Windows Phone實用開發技巧(40):使用NGif創建GIF圖片


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圖片以及最后在程序中顯示制作的圖片。首頁運行效果如下:

20120911wp701

圖片選擇的模板如下:

        <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,其中很多代碼可以優化,大家可以酌情使用本示例中的代碼。

源代碼可以在這里找到。


免責聲明!

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



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