WP8.1下用程序生成Gif动画实例教程

Gif文件编码方法

先简单介绍一下编码的方法。

1、调用BitmapEncoder.CreateAsync静态方法实例化编码器,要创建GIF编码器,可以在调用方法时,指定表示GIF编码器的GUID,这个GUID不用特意去记,因为访问BitmapEncoder.GifEncoderId静态属性就能得到。

2、调用SetPixelData方法设置当前帧的图像数据。注意,编码器对象在创建实例后,默认处于第一帧,因此对于设置第一张图片的数据时,可以直接调用SetPixelData方法。

3、从第二帧开始,需要先调用GoToNextFrameAsync方法向后移动一帧,然后才调用SetPixelData方法设置数据。设置完最后一帧后就不用再调用GoToNextFrameAsync,因为后面没有内容了,如果调用GoToNextFrameAsync创建新帧而不写入数据,会引发异常。

4、关闭相关的流。

比如下面示例:

 

BitmapEncoder encoder= await BitmapEncoder.CreateAsync(BitmapEncoder.GifEncoderId, outStream);

      ……

 encoder.SetPixelData(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, decoder.PixelWidth, decoder.PixelHeight, decoder.DpiX, decoder.DpiY, data);
   ……
    if ( 不是最后一帧 )
    {
        await encoder.GoToNextFrameAsync();
    }

 

设置时间间隔

如果要让gif产生动画,就得设置延迟时间,即时间间隔。要通过写入图像元数据的方法来实现。

表示时间间隔的元数据路径为:

 

BitmapProperties pv = encoder.BitmapProperties;
    Dictionary<string, BitmapTypedValue> props = new Dictionary<string, BitmapTypedValue>();
    ……

    // Delay表示每一帧的时间间隔,单位为1/100秒
    props.Add("/grctlext/Delay", new BitmapTypedValue(30, PropertyType.UInt16));
    await pv.SetPropertiesAsync(props); //写入元数据

 

元数据可以用字典数据结构来操作,Key为字段的路径,Value就是该元数据的值,由BitmapTypedValue类来封装元数据值。使用时通过以下构造函数来实例化。

public BitmapTypedValue ( object value, PropertyType type );

value就是元数据的值,类型为object,可以兼容各种值,type参数指定元数据的数据类型,由Windows.Foundation命名空间下的PropertyType枚举来规范。

Delay的值为 1 / 100秒,即0.01秒,如果设置为50,就表示动画每个帧的间隔为50 * 10 = 500毫秒。

设置delay后保存的gif文件已经有动画效果了,但是,它只播放一次就会停下来。多数情况下,我们都希望GIF动画是无限循环播放的,这就要设置其他的元数据值了。

无限循环播放

要让gif循环播放,需要指定两个值:

第一个值是 /appext/Application,这个值是必须的,而且是固定的,就是字符串“NETSCAPE2.0”的字节表示形式,注意是字节表示,不要直接设置字符串,该字符串转化为字节数组为11个字节。NetScape有一款浏览器,相信很多人都知道,当年我在Win 98下经常用这个浏览器的,呵呵,一直用到Win Me还在用。

第二个值是 /appext/Data。在C++中,这个值一般包括5个字节,不过我们在C#中放4个字节也没问题的(其实第五个字节是’‘,即NULL,表示结尾)。要实现无限循环播放,只要把下面字节数组写入/appext/Data即可。

3, 1, 0, 0

第一个字节为3,表示紧跟它后面的字节数,因为后面1、0、0是3个字节,所以它的值为3。

第二个字节必须为1,表示启用gif动画。

第三个字节表示循环播放的次数。0表示无限循环,如果希望动画播放5次就停下来,那就设置为5。通常都为0,因为我们都喜欢死循环。

第四个字节为有效高字位的迭代统计,我也不知道干吗用的,反正设置为0就行了。

其实,如果想让动画无限循环,只要记住3、1、0、0四个值就好了,直接背下来也无所谓,反正很好记。

生成GIF动画示例

这个示例把5张jpg图片合起来,变成一个GIF文件,并且有动画效果的。为了节省废话,我只帖上创建GIF的核心代码。

StorageFolder photoFolder = KnownFolders.PicturesLibrary;
    StorageFile newFile = await photoFolder.CreateFileAsync("newfile.gif",CreationCollisionOption.ReplaceExisting);
    IRandomAccessStream outStream = await newFile.OpenAsync(FileAccessMode.ReadWrite);
    BitmapEncoder encoder= await BitmapEncoder.CreateAsync(BitmapEncoder.GifEncoderId, outStream);
    // 元数据

    /*
     * /appext/Application的值是固定的,为“NETSCAPE2.0”,11个字节
     * /appext/Data设置循环播放,如果不设置该字段,则只播放一次。
     * Data的值是一组字节,由于将第一个字节设置为3,第二个字节设置为1即可以达到循环播放效果,
     * 其他字符可以为0;
     * 3 - 表示随后的字节块大小,后面1,0,0三个字节,所以为3;
     * 1 - 表示Gif使用动画;
     * 0 - 循环次数,0表示无限循环
     */

    BitmapProperties pv = encoder.BitmapProperties;
    Dictionary<string, BitmapTypedValue> props = new Dictionary<string, BitmapTypedValue>();
    byte[] buffer = System.Text.Encoding.UTF8.GetBytes("NETSCAPE2.0");
    // 此字段必须
    props.Add("/appext/Application", new BitmapTypedValue(buffer, PropertyType.UInt8Array));
    // 表示循环播放
    props.Add("/appext/Data", new BitmapTypedValue(new byte[] { 3, 1, 0, 0 }, PropertyType.UInt8Array));

    // Delay表示每一帧的时间间隔,单位为1/100秒
    props.Add("/grctlext/Delay", new BitmapTypedValue(30, PropertyType.UInt16));
    await pv.SetPropertiesAsync(props); //写入元数据

    for (short i = 1; i <= 5; i++)
    {
        Uri uri = new Uri("ms-appx:///Assets/" + i.ToString() + ".jpg");
        StorageFile inFile = await StorageFile.GetFileFromApplicationUriAsync(uri);
        IRandomAccessStream inStream = await inFile.OpenReadAsync();
        // 解码
        BitmapDecoder decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.JpegDecoderId, inStream);
        // 获取像素数据
        PixelDataProvider pxProvider = await decoder.GetPixelDataAsync();
        byte[] data = pxProvider.DetachPixelData();
        // 编码
        encoder.SetPixelData(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, decoder.PixelWidth, decoder.PixelHeight, decoder.DpiX, decoder.DpiY, data);
        inStream.Dispose();
        if (i < 5)
        {
            await encoder.GoToNextFrameAsync();
        }
    }

    await encoder.FlushAsync();
    outStream.Dispose();

 

下面gif图片就是用上面的示例创建的,一起来欣赏一下。

如何? 这些芙蓉花是不是很美?

===============================================

修订:

可能大家已经发现,上面生成的gif动画有点小问题,就是后一帧图片会与上一帧图片重叠,有时候我们是希望每一帧图片独立显示。所以在设置元数据时,可以把 /grctlext/Disposal 的值设置为2,表示清除上一帧图片。

props.Add("/grctlext/Disposal", new BitmapTypedValue((byte)2, PropertyType.UInt8));

再看看通过这样修改后生成的图片。

现在,每一帧图片就不会发生重叠了。

时间: 2024-10-06 22:54:57

WP8.1下用程序生成Gif动画实例教程的相关文章

Sass自动化处理CSS动画实例教程

有一天,Harry Roberts有一段有关于他网站上的代码在twitter求教,如果有可能,在某些方面得到改善.Harry Roberts做的是使用keyframes的carousel动画,所以说使用一些数学计算是有可能得到相应改善.     "Why do we have to learn algebra, Miss? We're never going to use it-" -Everyone in my maths class bit.ly/UaM2wf 有什么好主意? 据我

Fireworks利用滤镜工具制作Gif动画实例教程

gif文件: png文件: R: 看了"小可爱"转的用fireworks插件制作3D的gif动画,实在强大. 介绍这个插件的文章有差不多这样一句话:按下"导出"按钮,可能有类似死机现象,但是只要耐心等待,总会输出gif. 晕,我家里的机是n年前的老牌货,看来要另想办法了. 乱碰乱撞之下,意想不到的事情发生了----- 1. 新建一个150*100px大小的画布, 用"星型工具"画一个四叶草图案,为它加一个"纯色阴影滤"镜. 按

Flash制作卷轴动画实例教程

  用Flash软件制作书法卷轴动画,是考试中必考的试题,本文对Flash制作卷轴动画实例 进行了具体阐述供阅读.大家请仔细阅读下文! 1.新建文档,然后导入图片,在舞台的第一帧拖入图片,调节到合适的大小并按(F8)转化为影片剪辑元件(提示:转化为影片剪辑的目的是为了能够使用模糊滤镜) 2.新建层,复制图层1的第一帧,粘贴到图层2的第一帧,在第二层的第一帧选择影片剪辑元件,在属性栏选择-添加滤镜-模糊(15左右,视舞台大小及图片分辨率),在图层1和图层2的第90帧按F5插入帧(提示:90帧是影片

Flash设计制作可爱的小兔子跷跷板动画实例教程

  这个Flash实例制作了两只可爱的小兔子玩跷跷板的动画,主要用到椭圆工具.渐变填充和任意变形工具等,操作简单易懂,适合练习. 制作步骤: 1.新建一个默认大小的Flash文档.先画天空背景,用矩形工具画一个矩形,在对齐面板中按下"相对于舞台",再点"匹配宽和高"按钮,最后点"垂直中齐"和"水平中齐"按钮.与舞台对齐之后给矩形设置如下从白色到天蓝色的渐变,方式为"线性". 图1 2.草地.画一个草绿色的矩

Fireworks设计制作数字连续翻滚动画实例教程

  闲来无事,译了篇Fireworks(以下简称FW)的基础文章,效果如图: 由于浏览器的问题,大家看到的图片可能是静态的,但是把图片另存为到本地上,我们就可以看到此图片是动态的 这是一个大家可能都喜欢的简单动画技术,使用Fw中的"逐帧"制作出来的效果.大家可以用同样的方法做成倒计秒数的动画. 在Fireworks中打开一个新的画布,选择工具栏中的文本工具,输入第一个数字,并设置好文字的字体.像素大小等样式 打开帧面板,使用黑白选择工具,在面板是右上角点击,弹出下拉菜单,选择"

flash羽化遮罩动画实例教程

  一.打开flash软件 二.新建文档,参数默认 三.导入两张图片到库 四.在默认图层从库中拖入一张图片对齐场景作为背景锁住该层 五.添加一个图层,从库中再拖入一张图片对齐场景 模糊遮罩及其制作简介 1.右键点击图片转化为影片剪辑元件 2.选中该剪辑,打开属性面板给它实例名"p1c",在"运用位图缓存"的前面打上勾,锁住该图层 六.再添加一个图层,用椭圆工具无笔触颜色填充颜色任意画一个10*10的圆 1.选中圆居中对齐 2.右键点击圆转化为影片剪辑 3.选中这个圆

Flash模仿制作毛笔写字效果动画实例教程

  1.首先新建一Flash文档,修改文档尺寸为,宽500,高350,设背景颜色为#006666.然后制作所需的元件: 制作卷轴: 点击插入菜单-选择"新建元件",在弹出的对话框上名称:填上"轴",行为:选择"图形"然后确定, 使用矩形工具,关闭颜色工具的边框,选择油漆筒,打开右边的混色器将颜色状态设置成线性,将线性渐变设置成如图所示, 用矩形工具画出卷轴主要部分,使用任意变形工具调整其形状并将中心小圆与小十字对齐,再用同样方法在上下两端画出黑色

css3 loading: 3款漂亮的CSS3 Loading动画实例教程

HTML第1个例子中的HTML标记非常简单,我们在页面上创建了一个ul列表标记,并在其内部创建了几个div来控制它的总体进度动画,代码如下: 12345678910111213141516171819202122 <ul id="progress">    <li>    <div id="layer1" class="ball"></div> <!-- layer1 control dela

Flash设计制作晶莹剔透的沙漏反转动画实例教程

  本教程主要使用Flash制作晶莹剔透的沙漏流动动画教程,效果做的非常的漂亮,喜欢的朋友让我们一起来学习吧. 先看看效果图 下面是教程