[开源]基于WPF实现的Gif图片分割器,提取GIf图片中的每一帧
不知不觉又半个月没有更新博客了,今天终于抽出点时间,来分享一下前段时间的成果。
在网上,我们经常看到各种各样的图片,尤其是GIF图片的动态效果,让整个网站更加富有表现力!有时候,我们看到一些比较好看的GIF图片或者一些奇特的Gif图片,我们想要停留在某一帧看的清楚一点或者了解这个Gif动画到底是怎么实现的,怀着这种好奇的心理,我们来看一下,今天的开源项目,用WPF来实现GIF图片的预览和分离和保存。
1、GIF简介
GIF(Graphics Interchange Format)是CompuServe公司开发的图像文件存储格式,1987年开发的GIF文件格式版本号是GIF87a,1989年进行了扩充,扩充后的版本号定义为GIF89a。 GIF图像文件以数据块(block)为单位来存储图像的相关信息。一个GIF文件由表示图形/图像的数据块、数据子块以及显示图形/图像的控制信息块组成,称为GIF数据流(Data Stream)。数据流中的所有控制信息块和数据块都必须在文件头(Header)和文件结束块(Trailer)之间。
GIF文件格式采用了LZW(Lempel-Ziv Walch)压缩算法来存储图像数据,定义了允许用户为图像设置背景的透明(transparency)属性。此外,GIF文件格式可在一个文件中存放多幅彩色图形/图像。如果在GIF文件中存放有多幅图,它们可以像演幻灯片那样显示或者像动画那样演示。
2、GIF文件结构
GIF文件结构的典型结构如图6-01所示。为下文说明方便,在构件左边加了编号。

数据块可分成3类:
控制块(Control Block),图形描绘块(Graphic-Rendering Block)和专用块(Special Purpose Block)。
(1) 控制块:
控制块包含有用来控制数据流(Data Stream)或者设置硬件参数的信息,其成员包括:
GIF文件头(Header)
逻辑屏幕描述块(Logical Screen Descriptor)
图形控制扩展块(Graphic Control Extension)
文件结束块(Trailer)
(2) 图形描绘块:
包含有用来描绘在显示设备上显示图形的信息和数据,其成员包括:
图像描述块(Image Descriptor)
无格式文本扩展块(Plain Text Extension)
全局调色板、局部调色板、图像压缩数据和图像说明扩充块。
(3) 特殊用途数据块:
包含有与图像处理无关的信息,其成员包括:
注释扩展块(Comment Extension)
应用扩展块(Application Extension)
除了在控制块中的逻辑屏幕描述块(Logical Screen Descriptor)和全局彩色表(Global Color Table)的作用范围是整个数据流(Data Stream)之外, 所有其他控制块仅跟在它们后面的图形描绘块。
3、GIF结构详解
由于GIF结构比较复杂,我们就简单讲解一下GIF的文件头吧,因为我们要用到,更多的资料请参看百度文库:http://wenku.baidu.com/view/2c0feaa6f524ccbff121841d.html。
(1)文件头描述块(Header)定义GIF数据流(GIF Data Stream),它的结构如图6-02所示。文件头描述块(Header)由GIF标记域(Signature)和版本号(Version)域组成,是一个由6个固定字节组成的数据块,它们用来说明使用的文件格式是GIF格式及当前所用的版本号。GIF标记域(Signature)存放的是“GIF”,版本号域存放的是1987年5月发布的“87a”或者1989年7月发布的“89a”,或者更加新的版本号。

这里我们识别一个图片是不是GIF文件,就是判断文件的前三个字节是不是GIF,就算是图片呗重命名为jpg或者其他的,只要用浏览器打开,都是可以正常显示的,这也就是为什么有些jpg图片也会动的原因。同理PNG图片的前三个图片是PNG.
(2)逻辑屏幕描述块(Logical Screen Descriptor)包含定义图像显示区域的参数,包括背景颜色信息。这个数据块中的坐标相对于虚拟屏幕的左上角,不一定是指显示屏的绝对坐标,这就意味可以参照窗口软件环境下的窗口坐标或者打印机坐标来设计图像显示程序。逻辑屏幕描述块的结构如图6-03所示:

这里我们看到GIF的字段,可以读取GIF图片的实际高度和宽度,到这里就差不多了,其他的大家看百度文库的文档吧,我就不再说了。
上面给大家讲了那么多的GIF文件的东西,可能大家看的有点不耐烦,目的主要是为了让大家了解GIF的结构,这样才能更好的读懂项目里面的代码。下面来看一段读取GIF文件信息的代码,体会一下:
private void ShowGifInfo(byte[] buffer, string imgPath)
{
string type = ASCIIEncoding.ASCII.GetString(buffer, , ); //前3个字节,标识"GIF"
string version = ASCIIEncoding.ASCII.GetString(buffer, , );//3~6个字节,版本号
int logicalWidth = BitConverter.ToUInt16(buffer, );//第7,8两个字节,宽度
int logicalHeight = BitConverter.ToUInt16(buffer, ); //第9,10两个字节,高度 txtFileName.Text = "图片路径: " + imgPath;
txtTotalFrames.Text = "总帧数: " + bd.Frames.Count.ToString();
txtRealHeight.Text = "实际高度: " + logicalHeight.ToString() + "px";
txtRealWidth.Text = "实际宽度: " + logicalWidth.ToString() + "px";
txtVersion.Text = "Gif版本: " + version;
}
这段代码读取和显示GIF的标识、版本号、宽度和高度信息。可以看到,都是读取文件的特定的几个字节。
下面来看看这个开源项目的界面吧,首先GIF图片,如下:

看起来很炫,是吧,然后我们来看看到底都有哪些帧组成的,如图:

我们可以看到GIF的版本号和帧数,一共是8帧,也就是八张图片,我们点击另存为,输入图片名称,如Img,保存每一帧图片,如图:

我们看到,八张图片都分离出来了,看起来好漂亮啊,图片的名字就是我们刚才输入的名称后面加上编号。
下面我们来看几个比较神秘的GIF,如下图:

这几张图片看起来是无限循环的,没有停顿,那么他们到底有多少帧呢?这个就留给大家去探索吧!

叫你看完不点推荐,见你看完不点推荐……
Github开源地址:https://github.com/yunfeifei/GifSeparator/

项目中有不足的地方,大家可以留言指出,我会第一时间修改更正!同时欢迎大家一起进QQ群学习交流~
作者:雲霏霏
QQ交流群:243633526
博客地址:http://www.cnblogs.com/yunfeifei/
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
如果大家感觉我的博文对大家有帮助,请推荐支持一把,给我写作的动力。
[开源]基于WPF实现的Gif图片分割器,提取GIf图片中的每一帧的更多相关文章
- WPF 把图片分割成两份自动翻页 WpfFlipPageControl:CtrlBook 书控件
原文:WPF 把图片分割成两份自动翻页 WpfFlipPageControl:CtrlBook 书控件 版权声明:本文为博主原创文章,需要转载尽管转载. https://blog.csdn.net/z ...
- 《Dotnet9》系列-开源C# WPF控件库3《HandyControl》强力推荐
大家好,我是Dotnet9小编,一个从事dotnet开发8年+的程序员.我最近开始写dotnet分享文章,希望能让更多人看到dotnet的发展,了解更多dotnet技术,帮助dotnet程序员应用do ...
- (四)开源C# WPF控件库《AduSkin – UI》
微信公众号:[Dotnet9的博客],网站:[Dotnet9],问题或建议:[请网站留言], 如果对您有所帮助:[欢迎赞赏]. 开源C# WPF控件库系列: (一)开源C# WPF控件库<Mat ...
- Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图
Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图 分类: OpenCV图像处理2013-02-21 21:35 6459人阅读 评论(8) 收藏 举报 原文链接 ht ...
- 纠错:基于FPGA串口发送彩色图片数据至VGA显示
今天这篇文章是要修改之前的一个错误,前面我写过一篇基于FPGA的串口发送图片数据至VGA显示的文章,最后是显示成功了,但是显示的效果图,看起来确实灰度图,当时我默认我使用的MATLAB代码将图片数据转 ...
- 第八节、图片分割之GrabCut算法、分水岭算法
所谓图像分割指的是根据灰度.颜色.纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出相似性,而在不同区域间呈现出明显的差异性.我们先对目前主要的图像分割方法做个概述,后面再 ...
- (转)基于 WPF + Modern UI 的 公司OA小助手 开发总结
原文地址:http://www.cnblogs.com/rainlam163/p/3365181.html 前言: 距离上一篇博客,整整一个月的时间了.人不能懒下来,必须有个阶段性的总结,算是对我这个 ...
- 基于WPF系统框架设计(5)-Ribbon整合Avalondock 2.0实现多文档界面设计(二)
AvalonDock 是一个.NET库,用于在停靠模式布局(docking)中排列一系列WPF/WinForm控件.最新发布的版本原生支持MVVM框架.Aero Snap特效并具有更好的性能. Ava ...
- 基于 WPF + Modern UI 的 公司OA小助手 开发总结
前言: 距离上一篇博客,整整一个月的时间了.人不能懒下来,必须有个阶段性的总结,算是对我这个阶段的一个反思.人只有在总结的过程中才会发现自己的不足. 公司每天都要在OA系统上上班点击签到,下班点击签退 ...
随机推荐
- Android-Menu [使用C# And Java实现]
本篇是对安卓菜单使用编程方式实现,当然可以使用XML的方式完成同样的功能,基本Java和C#写法都是一致的,所以使用XML的方式在本篇中使用Java演示,需要注意的是,对于如果不是VS开发的话,那么资 ...
- 优化Web中的性能
优化Web中的性能 简介 web的优化就是一场阻止http请求最终访问到数据库的战争. 优化的方式就是加缓存,在各个节点加缓存. web请求的流程及节点 熟悉流程及节点,才能定位性能的问题.而且优化的 ...
- Servlet读取Excel标准化数据库过程记录
完成数据库的连接 获取连接参数 拷贝1.数据库URL 2.驱动程序类 3.用户 编写Servlet 1.创建连接对象 Connection con = null; PreparedStatement ...
- 转:Delphi的类与继承(VB与delphi比较)
既然已经做出了com程序用delphi来开发的决定,那当然就要对delphi进行一些深入的了解.有人说delphi是一个用控件堆砌起来的工具,和vb没什么两样:也有人说dephi实际上是面向过程的,他 ...
- 【oracle】union、union all、intersect、minus 的用法及区别
一.union与union all 首先建两个view create or replace view test_view_1 as as c from dual union as c from dua ...
- 搜索引擎Query Rewrite
中心词抽取项目总结 B2B国际站Query重写.ppt 达观数据搜索引擎的Query自动纠错技术和架构详解 Natural Language Processing Simrank++ Query re ...
- CodeIgniter 3.0问题集锦
1.由于ci 3.0的session采用文件存储,在配置好session存储的目录后,在使用时如果遇到如下session错误. 此处 fc 目录为我设置的session目录. 解决将fc目录权限设为7 ...
- 弱省互测#0 t1
题意 给一个\(N \times M\)的01网格,1不能走,从起点\((1, 1)\)走到\((N, M)\),每次只能向下或向右走一格,问两条不相交的路径的方案数.(n, m<=1000) ...
- 如何使CEF支持Flash
方法一:复制Chrome浏览器下的pepperFlash,通过cef命令行参数设置路径. public Form1() { InitializeComponent(); InitializeChrom ...
- vertical-align和line-height的那些事
可能是又遇到了瓶颈,好长时间感觉css上没什么可看.从来没觉得css有什么难,什么盒模型和各种流也觉得理解起来毫不费力,但好像仅限于此.对一些属性仅限于常用,有时会去做实验验证一些属性,过后就忘了.现 ...