wpf GifBitmapDecoder 解析 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;
}
参见: 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
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
wpf GifBitmapDecoder 解析 gif 格式的更多相关文章
- WP8解析JSON格式(使用DataContractJsonSerializer类)(推荐)
DataContractJsonSerializer是.NET自带的类,在解析JSON格式的时候使用起来方便快捷,至于生成方面由于暂时没用到就没去看了.使用需要引用System.Runtime.Ser ...
- WP8解析JSON格式(使用Newtonsoft.Json包)
DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式. 这里举一个简单的解析JSON格式的例子(更多JSON操作): { "response&q ...
- WP8解析XML格式文件
DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式,如果要返回XML格式的话,需要在加上format=xml. 这里举一个简单的解析XML格式的例子(更 ...
- NSXMLParser解析xml格式
NSXMLParser解析xml格式的数据 用法如下: 首先,NSXMLParser必须继续NSXMLParserDelegate协议 @interface XMLHelper : NSObject ...
- C语言解析Ini格式文件
引用别人的博文: http://www.open-open.com/lib/view/open1402278076447.html 可以解析 INI 格式的字符串.解析文件.保存到文件. 下面是头文件 ...
- 解析json格式数据
实现目标 读取文件中的json格式数据,一行为一条json格式数据.进行解析封装成实体类. 通过google的Gson对象解析json格式数据 我现在解析的json格式数据为: {",&qu ...
- 用GSON解析Json格式数据
GSON是谷歌提供的开源库,用来解析Json格式的数据,非常好用.如果要使用GSON的话,则要先下载gson-2.2.4.jar这个文件,如果是在Android项目中使用,则在Android项目的li ...
- 实现android上解析Json格式数据功能
实现android上解析Json格式数据功能,该源码转载于安卓教程网的,http://android.662p.com ,个人感觉还不错的,大家可以看看一下吧. package com.practic ...
- Java 解析epub格式电子书,helloWorld程序,附带源程序和相关jar包
秀才坤坤出品 一.epub格式电子书 相关材料和源码均在链接中可以下载:http://pan.baidu.com/s/1bnm8YXT 包括 1.JAVA项目工程test_epub,里面包括了jar包 ...
随机推荐
- 【Alpha】——Fourth Scrum Meeting
一.今日站立式会议照片 二.每个人的工作 成员 昨天已完成的工作 今天计划完成的工作 李永豪 完善添加功能 测试统计功能 郑靖涛 完善删除功能 着手编写报表设计 杨海亮 完善查找功能 协助编写统计功能 ...
- vbs文件共享变量与函数的方法
参考资料: vbs能否像其他编程语言一样,把写好的代码打包成类库以供调用呢?经过搜索和实验,发现vbs文件之间可以互相调用并共享变量,这样我们就不用再反复地编写轮子了. 以下是一个调用实例: ==== ...
- 201521123088《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...
- 201521123044 《Java程序设计》第14周学习总结
1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 友情提示:导图用ctrl+鼠标滚轮放大看更清楚些 2. 书面作业 1. MySQL数据库基本操作 建立数据库, ...
- 解决vsftp无法启动问题(转)
[root@node11 ~]# service vsftpd restartShutting down vsftpd: [F ...
- 接口测试入门(3)--使用httpClient进行登录用例操作/set-cookies验证/ List<NameValuePair>设置post参数/json解析
(最近学的都是很基础的接口测试,都是基于UI界面可见的接口,就是发请求,接收响应,分析返回的结果,校验,对共通模块进行封装,仅此而已,其实做自动化的思路基本都是如此,UI也是.) 现在开始用httpC ...
- Python-老男孩-02_装饰器_面向对象_封装_继承_异常_接口_数据库
装饰器其实也是一个函数,它的参数是一个函数 ; 其它函数与装饰器之间建立联系是通过 @装饰器函数名, 感觉有点像Spring的面向切面编程 装饰器函数,如何处理原函数的参数.? 装饰器 原函数返回值 ...
- MongoDB 复制篇
mongoDB 复制篇 复制集简介 Mongodb复制集由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点,Mongodb Driver(客户端)的所有数据都写 ...
- 根据HttpServletRequest获取用户真实IP地址
原因: 当我们通过request获取客户端IP时,自身服务器通常会为了保护信息或者负载均衡的目的,对自身服务器做反向代理.此时如果我们通过request.getRemoteAddr();可能获取到的是 ...
- Fiddler抓包工具使用详解
一.Fiddler简介 Fiddler是最强大最好用的Web调试工具之一, 它能记录所有客户端和服务器的http和https请求.允许你监视.设置断点.甚至修改输入输出数据.Fiddler包含了一个强 ...