您的位置:首页 > 其它

Windows Phone实用开发技巧(40):使用NGif创建GIF图片

2012-09-11 10:23 561 查看
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,其中很多代码可以优化,大家可以酌情使用本示例中的代码。

源代码可以在这里找到。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: