title author date CreateTime categories
wpf GifBitmapDecoder 解析 gif 格式
lindexi
2018-2-13 17:23:3 +0800
2018-2-13 17:23:3 +0800
WPF gif

在网上有很多图片都是gif,那么如何在 wpf 解析 gif?
本文告诉大家如何使用 GifBitmapDecoder 把gif分开为一张一张,获得他的信息。

如果需要把一个 gif 分开,使用的代码很简单

            var file = "E:\\林德熙\\测试文件\\2017年9月1日 10.gif";
var stream = new FileStream(file, FileMode.Open);
var decoder = new GifBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);

从 decoder 就可以获得每个图片,例如写一个按钮,按一下就切换一个图片。

      private int n = 0;

        private void Button_OnClick(object sender, RoutedEventArgs e)
{
var t = decoder.Frames[n]; Image.Source = t;
n++;
if (n >= decoder.Frames.Count)
{
n = 0;
}
}

按钮点击如上面代码,可以看到 decoder 把 gif 分开很简单,但是如何获得一帧的时间。如果在 wpf 获得 gif 图片间隔,就需要一些特殊方法。

先创建一个类 用于获得 gif 的信息,需要知道,每个gif的里面的图片都有信息。

        class FrameInfo
{
public TimeSpan Delay { get; set; }
public FrameDisposalMethod DisposalMethod { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public double Left { get; set; }
public double Top { get; set; } public Rect Rect
{
get { return new Rect(Left, Top, Width, Height); }
}
}

其中 Delay 就是两个图片播放的时间,FrameDisposalMethod表示两张图片是如何播放,完全替换前一张还是在前一张基础继续显示。

获得 gif 的信息需要使用 GetQuery ,这个方法不好用,于是使用下面代码把他转类型

        private static T? GetQueryOrNull<T>(this BitmapMetadata metadata, string query)
where T : struct
{
if (metadata.ContainsQuery(query))
{
object value = metadata.GetQuery(query);
if (value != null)
return (T) value;
}
return null;
}

可以看到 decoder 的每个图片的 Metadata 是 ImageMetadata ,而且wr也没说它里面有哪些数据。

实际可以使用BitmapMetadata获得每个图片信息,因为Metadata实际是BitmapMetadata,通过/grctlext/Delay可以获得两个图片的时间,/grctlext/Disposal可以获得两个图片是如何显示,/imgdesc/Width 可以获得宽度。于是使用下面函数可以获得图片信息

        public static FrameInfo GetFrameInfo(BitmapFrame frame)
{
var frameInfo = new FrameInfo
{
Delay = TimeSpan.FromMilliseconds(100),
DisposalMethod = FrameDisposalMethod.Replace,
Width = frame.PixelWidth,
Height = frame.PixelHeight,
Left = 0,
Top = 0
}; BitmapMetadata metadata;
try
{
metadata = frame.Metadata as BitmapMetadata;
if (metadata != null)
{
const string delayQuery = "/grctlext/Delay";
const string disposalQuery = "/grctlext/Disposal";
const string widthQuery = "/imgdesc/Width";
const string heightQuery = "/imgdesc/Height";
const string leftQuery = "/imgdesc/Left";
const string topQuery = "/imgdesc/Top"; var delay = metadata.GetQueryOrNull<ushort>(delayQuery);
if (delay.HasValue)
frameInfo.Delay = TimeSpan.FromMilliseconds(10 * delay.Value); var disposal = metadata.GetQueryOrNull<byte>(disposalQuery);
if (disposal.HasValue)
frameInfo.DisposalMethod = (FrameDisposalMethod) disposal.Value; var width = metadata.GetQueryOrNull<ushort>(widthQuery);
if (width.HasValue)
frameInfo.Width = width.Value; var height = metadata.GetQueryOrNull<ushort>(heightQuery);
if (height.HasValue)
frameInfo.Height = height.Value; var left = metadata.GetQueryOrNull<ushort>(leftQuery);
if (left.HasValue)
frameInfo.Left = left.Value; var top = metadata.GetQueryOrNull<ushort>(topQuery);
if (top.HasValue)
frameInfo.Top = top.Value;
}
}
catch (NotSupportedException)
{
} return frameInfo;
}

这个方法实际上性能不好,如果需要一个可以用的gif解析,请看我的博客WPF 播放 gif

参见: http://www.thomaslevesque.com/2011/03/27/wpf-display-an-animated-gif-image/

http://stackoverflow.com/questions/210922/how-do-i-get-an-animated-gif-to-work-in-wpf

2018-2-13-wpf-GifBitmapDecoder-解析-gif-格式的更多相关文章

  1. wpf GifBitmapDecoder 解析 gif 格式

    在网上有很多图片都是gif,那么如何在 wpf 解析 gif? 本文告诉大家如何使用 GifBitmapDecoder 把gif分开为一张一张,获得他的信息. 如果需要把一个 gif 分开,使用的代码 ...

  2. Python3基础 json.loads 解析json格式的数据,得到一个字典

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  3. C#关于时间(获取特定格式的时间及多种方式获取当前时间戳)以及10位和13位时间戳转为特定格式

    C#关于时间(获取特定格式的时间及多种方式获取当前时间戳)以及10位和13位时间戳转为特定格式 置顶 2018年03月06日 19:16:51 黎筱曦 阅读数:19098 标签: C#时间 更多 个人 ...

  4. WP8解析JSON格式(使用DataContractJsonSerializer类)(推荐)

    DataContractJsonSerializer是.NET自带的类,在解析JSON格式的时候使用起来方便快捷,至于生成方面由于暂时没用到就没去看了.使用需要引用System.Runtime.Ser ...

  5. WP8解析JSON格式(使用Newtonsoft.Json包)

    DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式. 这里举一个简单的解析JSON格式的例子(更多JSON操作): { "response&q ...

  6. WP8解析XML格式文件

    DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式,如果要返回XML格式的话,需要在加上format=xml. 这里举一个简单的解析XML格式的例子(更 ...

  7. NSXMLParser解析xml格式

    NSXMLParser解析xml格式的数据 用法如下: 首先,NSXMLParser必须继续NSXMLParserDelegate协议 @interface XMLHelper : NSObject ...

  8. C语言解析Ini格式文件

    引用别人的博文: http://www.open-open.com/lib/view/open1402278076447.html 可以解析 INI 格式的字符串.解析文件.保存到文件. 下面是头文件 ...

  9. 解析json格式数据

    实现目标 读取文件中的json格式数据,一行为一条json格式数据.进行解析封装成实体类. 通过google的Gson对象解析json格式数据 我现在解析的json格式数据为: {",&qu ...

  10. 用GSON解析Json格式数据

    GSON是谷歌提供的开源库,用来解析Json格式的数据,非常好用.如果要使用GSON的话,则要先下载gson-2.2.4.jar这个文件,如果是在Android项目中使用,则在Android项目的li ...

随机推荐

  1. ELK4之进阶学习

    1.精确查找和模糊查找(term和match的区别) match经过分析(analyer)的, term是不经过分词,直接去倒排索引中查找精确的值. 2.建议器的简介(最左前缀或者自带的做) (1)直 ...

  2. iPhone 7 Plus 维修记 (一)(2019-08-07)

    iPhone 7 Plus 维修记 问题 电池鼓包,屏幕已经被撑起,偶尔死机突然关机. 分析 初步分析是电池损坏. 维修 由于电池没有双易拉条需要将后壳加热后再取出电池. 更换电池后测试,发现电量一会 ...

  3. Xcode10 import导入文件的坑

    更新了10.0的Xcode,踩了两个坑,记录一下. #import "" 双引号内输入任何字符 都会导致Xcode崩溃 解决方案: target - buildSettings - ...

  4. ArcGIS 发布高程服务。10.4

    ArcGIS 发布高程必须是10.21以上,我用10.4. 前端用ArcGIS For API 4.x. ARCGIS很早之前有CS版本的ArcScene,可查看高程TIF文件,但机制和BS的完全不同 ...

  5. cocos2d-x 特效集合

    本文转载自:http://www.cnblogs.com/linux-ios/archive/2013/04/09/3009292.html bool HelloWorld::init() { /// ...

  6. idea 启动一直一直build以及勉勉强强的解决方案

    周日做了一个密匙解析的功能,在idea的springboot项目的该类上写了个main方法测试,当时一直提示build,没在意,直接打开eclipse上写 今天早上发现 idea启动springboo ...

  7. 杭电多校第二场1012 L - Longest Subarray ce 线段树

    这题是真的秀...我服了...线段树用好了,感觉什么都可以写... 题目大意:给你一个串,问满足以下条件的子串中最长的是多长:对于每个数字,要么在这个子串没出现过,要么出现次数超过k次. 我们对于每一 ...

  8. kuangbin专题-连通图A - Network of Schools

    这道题的意思是就是 问题 1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件. 2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校 ...

  9. 2018-2-13-win10-uwp-获得Slider拖动结束的值

    title author date CreateTime categories win10 uwp 获得Slider拖动结束的值 lindexi 2018-2-13 17:23:3 +0800 201 ...

  10. JavaScript 拖曳和居中问题

    今天遇到了一个问题,是这样的,有一个div盒子,实现盒子居中,居中的样式是这样的见下 #box{ width:300px; height:150px; position:absolute; left: ...