技术开发 频道

[WPF疑难]在WPF中显示动态GIF


【IT168技术文档】

  在我们寻求帮助的时候,最不愿意听到的答复是:很抱歉,在当前版本的产品中还没有实现该功能... 在WPF中显示动态的GIF图像时便遇到了这样的问题,WPF中强大的Image控件却不支持动态的GIF(其只能显示第一帧).当然,我们可以说WPF 强大的动画能力,让我们完全有理由抛弃传统的GIF动画,但如某种情况下如果你觉得使用动态的GIF更合适的话(比如QQ表情,因为GIF是利于保存和传输的),没关系,本篇随笔将帮助你解决这个问题.

  1,曾有过的尝试:
  我们在实际开发过程中也遇到显示动态GIF的问题.发现普通的Image控件不能正常显示后,我们又发现网页浏览器却是可以的,以及 windows XP的"图片和传真查看器"也可以,但"Window Live照片库"却不可以.所以我们最初打算使用通过包装WebBrowseControl来实现,即是在WPF中host一个.net2.0中的浏览器控件,然后让该浏览器来实现图片,成功了,但麻烦的事情是鼠标右键可以点出网页的上下文菜单.我们放弃了该方案,除了不愿意花时间来屏蔽上下文菜单和浏览器控件的多余功能外,同时我们的觉得浏览器控件过于"重量级",有点杀鸡用牛刀的感觉.另外,你可能会想到使用WPF中的Frame控件,但也会得到上述结果.另外,有网友说可以使用MediaElement控件,但大都没有成功,我也没有(可能是RP不够哈,呵呵...)

  2,GifBitmapDecoder
  我们发现WPF中有一个名为GifBitmapDecoder的类,其可以将动态GIF分解成很多帧并保存在一个列表中,每一帧为一个BitmapFrame类型的对象,其父类为BitmapSource,这也就意味着,我们可以将每一帧赋值给一个Image控件的Source属性,这样我们可以得到针对GIF各帧的Image系列:
GifBitmapDecoder decoder = new GifBitmapDecoder( new Uri("OH.gif", UriKind.Relative), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); foreach (BitmapFrame f in decoder.Frames) { Image image = new Image(); image.Source = f; this.panel1.Children.Add(image); }
3,解析GIF
要解析文件就必须知道文件的存储结构,比如,得到帧的显示时间的方法是这样的:
private int ParseGraphicControlExtension(byte[] gifData, int offset) { int returnOffset = offset; // Extension Block int length = gifData[offset + 2]; returnOffset = offset + length + 2 + 1; byte packedField = gifData[offset + 3]; currentParseGifFrame.disposalMethod = (packedField & 0x1C) >> 2; // Get DelayTime int delay = BitConverter.ToUInt16(gifData, offset + 4); currentParseGifFrame.delayTime = delay; while (gifData[returnOffset] != 0x00) { returnOffset = returnOffset + gifData[returnOffset] + 1; } returnOffset++; return returnOffset; }
0
相关文章