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

    源代码可以在这里找到。

  • 相关阅读:
    GitHub(二)之修改项目语言类型
    GitHub(一)之图片上传问题
    Git入门操作(一)
    树莓派小白教程六部曲
    关于Ajax请求的JS封装函数
    JavaScript运动_封装模板(支持链式运动、完美运动)
    NAT-地址转换技术的配置
    JAVA连接Sql-Server教程
    Kibana对数据的可视化
    浏览器渲染机制
  • 原文地址:https://www.cnblogs.com/alexis/p/create_and_display_gif_using_ngif.html
Copyright © 2020-2023  润新知