找回密码
 立即注册
首页 业界区 业界 C# WPF 内置解码器实现 GIF 动图控 ...

C# WPF 内置解码器实现 GIF 动图控件

齐娅晶 2025-8-11 09:21:20
相对于 WinForm PictureBox 控件原生支持动态 GIF,WPF Image 控件却不支持,让人摸不着头脑
常用方法

提到 WPF 播放动图,常见的方法有三种
MediaElement

使用 MediaElement 控件,缺点是依赖 Media Player,且不支持透明
  1. [/code][size=4]WinForm PictureBox[/size]
  2. 借助 WindowsFormsIntegration 嵌入 WinForm PictureBox,缺点是不支持透明
  3. [code]<WindowsFormsHost>
  4.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  5. </WindowsFormsHost>
复制代码
WpfAnimatedGif

引用 NuGet 包 WpfAnimatedGif,支持透明
  1. [/code]作者还有另一个性能更好、跨平台的 XamlAnimatedGif,用法相同
  2. [size=5]原生解码方法[/size]
  3. WPF 虽然原生 Image 不支持 GIF 动图,但是提供了 GifBitmapDecoder 解码器,可以获取元数据,包括循环信息、逻辑尺寸、所有帧信息等
  4. [size=4]判断是否循环和循环次数[/size]
  5. [code]int loop = 1;bool isAnimated = true;var decoder = new GifBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);var data = decoder.Metadata;if (data.GetQuery("/appext/Application") is byte[] array1){<WindowsFormsHost>
  6.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  7. </WindowsFormsHost>string appName = Encoding.ASCII.GetString(array1);<WindowsFormsHost>
  8.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  9. </WindowsFormsHost>if ((appName == "NETSCAPE2.0" || appName == "ANIMEXTS1.0")<WindowsFormsHost>
  10.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  11. </WindowsFormsHost><WindowsFormsHost>
  12.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  13. </WindowsFormsHost>&& data.GetQuery("/appext/Data") is byte[] array2)<WindowsFormsHost>
  14.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  15. </WindowsFormsHost>{<WindowsFormsHost>
  16.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  17. </WindowsFormsHost><WindowsFormsHost>
  18.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  19. </WindowsFormsHost>loop = array2[2] | array2[3]  (Uri)GetValue(UriSourceProperty);<WindowsFormsHost>
  20.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  21. </WindowsFormsHost><WindowsFormsHost>
  22.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  23. </WindowsFormsHost>set => SetValue(UriSourceProperty, value);<WindowsFormsHost>
  24.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  25. </WindowsFormsHost>}<WindowsFormsHost>
  26.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  27. </WindowsFormsHost>public Stream StreamSource<WindowsFormsHost>
  28.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  29. </WindowsFormsHost>{<WindowsFormsHost>
  30.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  31. </WindowsFormsHost><WindowsFormsHost>
  32.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  33. </WindowsFormsHost>get => (Stream)GetValue(StreamSourceProperty);<WindowsFormsHost>
  34.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  35. </WindowsFormsHost><WindowsFormsHost>
  36.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  37. </WindowsFormsHost>set => SetValue(StreamSourceProperty, value);<WindowsFormsHost>
  38.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  39. </WindowsFormsHost>}<WindowsFormsHost>
  40.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  41. </WindowsFormsHost>public int FrameIndex<WindowsFormsHost>
  42.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  43. </WindowsFormsHost>{<WindowsFormsHost>
  44.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  45. </WindowsFormsHost><WindowsFormsHost>
  46.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  47. </WindowsFormsHost>get => (int)GetValue(FrameIndexProperty);<WindowsFormsHost>
  48.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  49. </WindowsFormsHost><WindowsFormsHost>
  50.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  51. </WindowsFormsHost>private set => SetValue(FrameIndexProperty, value);<WindowsFormsHost>
  52.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  53. </WindowsFormsHost>}<WindowsFormsHost>
  54.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  55. </WindowsFormsHost>public Stretch Stretch<WindowsFormsHost>
  56.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  57. </WindowsFormsHost>{<WindowsFormsHost>
  58.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  59. </WindowsFormsHost><WindowsFormsHost>
  60.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  61. </WindowsFormsHost>get => (Stretch)GetValue(StretchProperty);<WindowsFormsHost>
  62.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  63. </WindowsFormsHost><WindowsFormsHost>
  64.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  65. </WindowsFormsHost>set => SetValue(StretchProperty, value);<WindowsFormsHost>
  66.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  67. </WindowsFormsHost>}<WindowsFormsHost>
  68.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  69. </WindowsFormsHost>public StretchDirection StretchDirection<WindowsFormsHost>
  70.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  71. </WindowsFormsHost>{<WindowsFormsHost>
  72.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  73. </WindowsFormsHost><WindowsFormsHost>
  74.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  75. </WindowsFormsHost>get => (StretchDirection)GetValue(StretchDirectionProperty);<WindowsFormsHost>
  76.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  77. </WindowsFormsHost><WindowsFormsHost>
  78.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  79. </WindowsFormsHost>set => SetValue(StretchDirectionProperty, value);<WindowsFormsHost>
  80.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  81. </WindowsFormsHost>}<WindowsFormsHost>
  82.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  83. </WindowsFormsHost>public bool IsLoading<WindowsFormsHost>
  84.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  85. </WindowsFormsHost>{<WindowsFormsHost>
  86.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  87. </WindowsFormsHost><WindowsFormsHost>
  88.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  89. </WindowsFormsHost>get => (bool)GetValue(IsLoadingProperty);<WindowsFormsHost>
  90.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  91. </WindowsFormsHost><WindowsFormsHost>
  92.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  93. </WindowsFormsHost>set => SetValue(IsLoadingProperty, value);<WindowsFormsHost>
  94.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  95. </WindowsFormsHost>}<WindowsFormsHost>
  96.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  97. </WindowsFormsHost>private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)<WindowsFormsHost>
  98.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  99. </WindowsFormsHost>{<WindowsFormsHost>
  100.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  101. </WindowsFormsHost><WindowsFormsHost>
  102.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  103. </WindowsFormsHost>((GifImage)d)?.OnSourceChanged();<WindowsFormsHost>
  104.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  105. </WindowsFormsHost>}<WindowsFormsHost>
  106.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  107. </WindowsFormsHost>private static void OnFrameIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)<WindowsFormsHost>
  108.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  109. </WindowsFormsHost>{<WindowsFormsHost>
  110.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  111. </WindowsFormsHost><WindowsFormsHost>
  112.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  113. </WindowsFormsHost>((GifImage)d)?.OnFrameIndexChanged();<WindowsFormsHost>
  114.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  115. </WindowsFormsHost>}<WindowsFormsHost>
  116.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  117. </WindowsFormsHost>private static void OnStrechChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)<WindowsFormsHost>
  118.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  119. </WindowsFormsHost>{<WindowsFormsHost>
  120.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  121. </WindowsFormsHost><WindowsFormsHost>
  122.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  123. </WindowsFormsHost>if (d is GifImage image && image.Content is Viewbox viewbox)<WindowsFormsHost>
  124.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  125. </WindowsFormsHost><WindowsFormsHost>
  126.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  127. </WindowsFormsHost>{<WindowsFormsHost>
  128.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  129. </WindowsFormsHost><WindowsFormsHost>
  130.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  131. </WindowsFormsHost><WindowsFormsHost>
  132.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  133. </WindowsFormsHost>viewbox.Stretch = image.Stretch;<WindowsFormsHost>
  134.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  135. </WindowsFormsHost><WindowsFormsHost>
  136.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  137. </WindowsFormsHost>}<WindowsFormsHost>
  138.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  139. </WindowsFormsHost>}<WindowsFormsHost>
  140.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  141. </WindowsFormsHost>private static void OnStrechDirectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)<WindowsFormsHost>
  142.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  143. </WindowsFormsHost>{<WindowsFormsHost>
  144.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  145. </WindowsFormsHost><WindowsFormsHost>
  146.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  147. </WindowsFormsHost>if (d is GifImage image && image.Content is Viewbox viewbox)<WindowsFormsHost>
  148.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  149. </WindowsFormsHost><WindowsFormsHost>
  150.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  151. </WindowsFormsHost>{<WindowsFormsHost>
  152.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  153. </WindowsFormsHost><WindowsFormsHost>
  154.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  155. </WindowsFormsHost><WindowsFormsHost>
  156.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  157. </WindowsFormsHost>viewbox.StretchDirection = image.StretchDirection;<WindowsFormsHost>
  158.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  159. </WindowsFormsHost><WindowsFormsHost>
  160.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  161. </WindowsFormsHost>}<WindowsFormsHost>
  162.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  163. </WindowsFormsHost>}<WindowsFormsHost>
  164.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  165. </WindowsFormsHost>Stream stream;<WindowsFormsHost>
  166.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  167. </WindowsFormsHost>Canvas canvas;<WindowsFormsHost>
  168.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  169. </WindowsFormsHost>FrameInfo[] frameInfos;<WindowsFormsHost>
  170.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  171. </WindowsFormsHost>Int32AnimationUsingKeyFrames animation;<WindowsFormsHost>
  172.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  173. </WindowsFormsHost>public GifImage()<WindowsFormsHost>
  174.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  175. </WindowsFormsHost>{<WindowsFormsHost>
  176.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  177. </WindowsFormsHost><WindowsFormsHost>
  178.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  179. </WindowsFormsHost>IsVisibleChanged += OnIsVisibleChanged;<WindowsFormsHost>
  180.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  181. </WindowsFormsHost><WindowsFormsHost>
  182.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  183. </WindowsFormsHost>Unloaded += OnUnloaded;<WindowsFormsHost>
  184.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  185. </WindowsFormsHost>}<WindowsFormsHost>
  186.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  187. </WindowsFormsHost>private void OnUnloaded(object sender, RoutedEventArgs e)<WindowsFormsHost>
  188.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  189. </WindowsFormsHost>{<WindowsFormsHost>
  190.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  191. </WindowsFormsHost><WindowsFormsHost>
  192.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  193. </WindowsFormsHost>Release();<WindowsFormsHost>
  194.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  195. </WindowsFormsHost>}<WindowsFormsHost>
  196.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  197. </WindowsFormsHost>private void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)<WindowsFormsHost>
  198.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  199. </WindowsFormsHost>{<WindowsFormsHost>
  200.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  201. </WindowsFormsHost><WindowsFormsHost>
  202.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  203. </WindowsFormsHost>if (IsVisible)<WindowsFormsHost>
  204.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  205. </WindowsFormsHost><WindowsFormsHost>
  206.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  207. </WindowsFormsHost>{<WindowsFormsHost>
  208.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  209. </WindowsFormsHost><WindowsFormsHost>
  210.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  211. </WindowsFormsHost><WindowsFormsHost>
  212.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  213. </WindowsFormsHost>StartAnimation();<WindowsFormsHost>
  214.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  215. </WindowsFormsHost><WindowsFormsHost>
  216.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  217. </WindowsFormsHost>}<WindowsFormsHost>
  218.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  219. </WindowsFormsHost><WindowsFormsHost>
  220.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  221. </WindowsFormsHost>else<WindowsFormsHost>
  222.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  223. </WindowsFormsHost><WindowsFormsHost>
  224.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  225. </WindowsFormsHost>{<WindowsFormsHost>
  226.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  227. </WindowsFormsHost><WindowsFormsHost>
  228.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  229. </WindowsFormsHost><WindowsFormsHost>
  230.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  231. </WindowsFormsHost>StopAnimation();<WindowsFormsHost>
  232.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  233. </WindowsFormsHost><WindowsFormsHost>
  234.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  235. </WindowsFormsHost>}<WindowsFormsHost>
  236.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  237. </WindowsFormsHost>}<WindowsFormsHost>
  238.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  239. </WindowsFormsHost>private void StartAnimation()<WindowsFormsHost>
  240.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  241. </WindowsFormsHost>{<WindowsFormsHost>
  242.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  243. </WindowsFormsHost><WindowsFormsHost>
  244.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  245. </WindowsFormsHost>BeginAnimation(FrameIndexProperty, animation);<WindowsFormsHost>
  246.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  247. </WindowsFormsHost>}<WindowsFormsHost>
  248.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  249. </WindowsFormsHost>private void StopAnimation()<WindowsFormsHost>
  250.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  251. </WindowsFormsHost>{<WindowsFormsHost>
  252.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  253. </WindowsFormsHost><WindowsFormsHost>
  254.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  255. </WindowsFormsHost>BeginAnimation(FrameIndexProperty, null);<WindowsFormsHost>
  256.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  257. </WindowsFormsHost>}<WindowsFormsHost>
  258.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  259. </WindowsFormsHost>private void Release()<WindowsFormsHost>
  260.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  261. </WindowsFormsHost>{<WindowsFormsHost>
  262.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  263. </WindowsFormsHost><WindowsFormsHost>
  264.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  265. </WindowsFormsHost>StopAnimation();<WindowsFormsHost>
  266.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  267. </WindowsFormsHost><WindowsFormsHost>
  268.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  269. </WindowsFormsHost>canvas?.Children.Clear();<WindowsFormsHost>
  270.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  271. </WindowsFormsHost><WindowsFormsHost>
  272.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  273. </WindowsFormsHost>stream?.Dispose();<WindowsFormsHost>
  274.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  275. </WindowsFormsHost><WindowsFormsHost>
  276.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  277. </WindowsFormsHost>animation = null;<WindowsFormsHost>
  278.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  279. </WindowsFormsHost><WindowsFormsHost>
  280.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  281. </WindowsFormsHost>frameInfos = null;<WindowsFormsHost>
  282.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  283. </WindowsFormsHost>}<WindowsFormsHost>
  284.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  285. </WindowsFormsHost>private async void OnSourceChanged()<WindowsFormsHost>
  286.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  287. </WindowsFormsHost>{<WindowsFormsHost>
  288.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  289. </WindowsFormsHost><WindowsFormsHost>
  290.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  291. </WindowsFormsHost>Release();<WindowsFormsHost>
  292.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  293. </WindowsFormsHost><WindowsFormsHost>
  294.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  295. </WindowsFormsHost>IsLoading = true;<WindowsFormsHost>
  296.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  297. </WindowsFormsHost><WindowsFormsHost>
  298.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  299. </WindowsFormsHost>FrameIndex = 0;<WindowsFormsHost>
  300.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  301. </WindowsFormsHost><WindowsFormsHost>
  302.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  303. </WindowsFormsHost>if (UriSource != null)<WindowsFormsHost>
  304.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  305. </WindowsFormsHost><WindowsFormsHost>
  306.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  307. </WindowsFormsHost>{<WindowsFormsHost>
  308.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  309. </WindowsFormsHost><WindowsFormsHost>
  310.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  311. </WindowsFormsHost><WindowsFormsHost>
  312.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  313. </WindowsFormsHost>stream = await ResourceHelper.GetStream(UriSource);<WindowsFormsHost>
  314.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  315. </WindowsFormsHost><WindowsFormsHost>
  316.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  317. </WindowsFormsHost>}<WindowsFormsHost>
  318.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  319. </WindowsFormsHost><WindowsFormsHost>
  320.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  321. </WindowsFormsHost>else<WindowsFormsHost>
  322.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  323. </WindowsFormsHost><WindowsFormsHost>
  324.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  325. </WindowsFormsHost>{<WindowsFormsHost>
  326.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  327. </WindowsFormsHost><WindowsFormsHost>
  328.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  329. </WindowsFormsHost><WindowsFormsHost>
  330.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  331. </WindowsFormsHost>stream = StreamSource;<WindowsFormsHost>
  332.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  333. </WindowsFormsHost><WindowsFormsHost>
  334.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  335. </WindowsFormsHost>}<WindowsFormsHost>
  336.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  337. </WindowsFormsHost><WindowsFormsHost>
  338.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  339. </WindowsFormsHost>if (stream != null)<WindowsFormsHost>
  340.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  341. </WindowsFormsHost><WindowsFormsHost>
  342.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  343. </WindowsFormsHost>{<WindowsFormsHost>
  344.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  345. </WindowsFormsHost><WindowsFormsHost>
  346.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  347. </WindowsFormsHost><WindowsFormsHost>
  348.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  349. </WindowsFormsHost>int loop = 1;<WindowsFormsHost>
  350.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  351. </WindowsFormsHost><WindowsFormsHost>
  352.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  353. </WindowsFormsHost><WindowsFormsHost>
  354.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  355. </WindowsFormsHost>bool isAnimated = true;<WindowsFormsHost>
  356.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  357. </WindowsFormsHost><WindowsFormsHost>
  358.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  359. </WindowsFormsHost><WindowsFormsHost>
  360.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  361. </WindowsFormsHost>var decoder = new GifBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);<WindowsFormsHost>
  362.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  363. </WindowsFormsHost><WindowsFormsHost>
  364.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  365. </WindowsFormsHost><WindowsFormsHost>
  366.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  367. </WindowsFormsHost>var data = decoder.Metadata;<WindowsFormsHost>
  368.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  369. </WindowsFormsHost><WindowsFormsHost>
  370.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  371. </WindowsFormsHost><WindowsFormsHost>
  372.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  373. </WindowsFormsHost>if (data.GetQuery("/appext/Application") is byte[] array1)<WindowsFormsHost>
  374.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  375. </WindowsFormsHost><WindowsFormsHost>
  376.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  377. </WindowsFormsHost><WindowsFormsHost>
  378.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  379. </WindowsFormsHost>{<WindowsFormsHost>
  380.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  381. </WindowsFormsHost><WindowsFormsHost>
  382.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  383. </WindowsFormsHost><WindowsFormsHost>
  384.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  385. </WindowsFormsHost><WindowsFormsHost>
  386.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  387. </WindowsFormsHost>string appName = Encoding.ASCII.GetString(array1);<WindowsFormsHost>
  388.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  389. </WindowsFormsHost><WindowsFormsHost>
  390.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  391. </WindowsFormsHost><WindowsFormsHost>
  392.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  393. </WindowsFormsHost><WindowsFormsHost>
  394.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  395. </WindowsFormsHost>if ((appName == "NETSCAPE2.0" || appName == "ANIMEXTS1.0")<WindowsFormsHost>
  396.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  397. </WindowsFormsHost><WindowsFormsHost>
  398.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  399. </WindowsFormsHost><WindowsFormsHost>
  400.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  401. </WindowsFormsHost><WindowsFormsHost>
  402.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  403. </WindowsFormsHost><WindowsFormsHost>
  404.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  405. </WindowsFormsHost>&& data.GetQuery("/appext/Data") is byte[] array2)<WindowsFormsHost>
  406.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  407. </WindowsFormsHost><WindowsFormsHost>
  408.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  409. </WindowsFormsHost><WindowsFormsHost>
  410.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  411. </WindowsFormsHost><WindowsFormsHost>
  412.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  413. </WindowsFormsHost>{<WindowsFormsHost>
  414.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  415. </WindowsFormsHost><WindowsFormsHost>
  416.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  417. </WindowsFormsHost><WindowsFormsHost>
  418.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  419. </WindowsFormsHost><WindowsFormsHost>
  420.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  421. </WindowsFormsHost><WindowsFormsHost>
  422.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  423. </WindowsFormsHost>loop = array2[2] | array2[3]  0)<WindowsFormsHost>
  424.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  425. </WindowsFormsHost><WindowsFormsHost>
  426.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  427. </WindowsFormsHost><WindowsFormsHost>
  428.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  429. </WindowsFormsHost>{<WindowsFormsHost>
  430.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  431. </WindowsFormsHost><WindowsFormsHost>
  432.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  433. </WindowsFormsHost><WindowsFormsHost>
  434.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  435. </WindowsFormsHost><WindowsFormsHost>
  436.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  437. </WindowsFormsHost>var previousInfo = frameInfos[index - 1];<WindowsFormsHost>
  438.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  439. </WindowsFormsHost><WindowsFormsHost>
  440.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  441. </WindowsFormsHost><WindowsFormsHost>
  442.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  443. </WindowsFormsHost><WindowsFormsHost>
  444.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  445. </WindowsFormsHost>switch (previousInfo.DisposalMethod)<WindowsFormsHost>
  446.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  447. </WindowsFormsHost><WindowsFormsHost>
  448.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  449. </WindowsFormsHost><WindowsFormsHost>
  450.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  451. </WindowsFormsHost><WindowsFormsHost>
  452.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  453. </WindowsFormsHost>{<WindowsFormsHost>
  454.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  455. </WindowsFormsHost><WindowsFormsHost>
  456.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  457. </WindowsFormsHost><WindowsFormsHost>
  458.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  459. </WindowsFormsHost><WindowsFormsHost>
  460.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  461. </WindowsFormsHost><WindowsFormsHost>
  462.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  463. </WindowsFormsHost>case DisposalMethod.RestoreBackground:<WindowsFormsHost>
  464.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  465. </WindowsFormsHost><WindowsFormsHost>
  466.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  467. </WindowsFormsHost><WindowsFormsHost>
  468.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  469. </WindowsFormsHost><WindowsFormsHost>
  470.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  471. </WindowsFormsHost><WindowsFormsHost>
  472.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  473. </WindowsFormsHost><WindowsFormsHost>
  474.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  475. </WindowsFormsHost>// 隐藏之前的所有帧<WindowsFormsHost>
  476.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  477. </WindowsFormsHost><WindowsFormsHost>
  478.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  479. </WindowsFormsHost><WindowsFormsHost>
  480.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  481. </WindowsFormsHost><WindowsFormsHost>
  482.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  483. </WindowsFormsHost><WindowsFormsHost>
  484.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  485. </WindowsFormsHost><WindowsFormsHost>
  486.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  487. </WindowsFormsHost>for (int i = 0; i < index - 1; i++)<WindowsFormsHost>
  488.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  489. </WindowsFormsHost><WindowsFormsHost>
  490.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  491. </WindowsFormsHost><WindowsFormsHost>
  492.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  493. </WindowsFormsHost><WindowsFormsHost>
  494.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  495. </WindowsFormsHost><WindowsFormsHost>
  496.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  497. </WindowsFormsHost><WindowsFormsHost>
  498.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  499. </WindowsFormsHost>{<WindowsFormsHost>
  500.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  501. </WindowsFormsHost><WindowsFormsHost>
  502.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  503. </WindowsFormsHost><WindowsFormsHost>
  504.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  505. </WindowsFormsHost><WindowsFormsHost>
  506.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  507. </WindowsFormsHost><WindowsFormsHost>
  508.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  509. </WindowsFormsHost><WindowsFormsHost>
  510.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  511. </WindowsFormsHost><WindowsFormsHost>
  512.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  513. </WindowsFormsHost>frameInfos[i].Frame.Visibility = Visibility.Hidden;<WindowsFormsHost>
  514.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  515. </WindowsFormsHost><WindowsFormsHost>
  516.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  517. </WindowsFormsHost><WindowsFormsHost>
  518.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  519. </WindowsFormsHost><WindowsFormsHost>
  520.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  521. </WindowsFormsHost><WindowsFormsHost>
  522.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  523. </WindowsFormsHost><WindowsFormsHost>
  524.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  525. </WindowsFormsHost>}<WindowsFormsHost>
  526.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  527. </WindowsFormsHost><WindowsFormsHost>
  528.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  529. </WindowsFormsHost><WindowsFormsHost>
  530.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  531. </WindowsFormsHost><WindowsFormsHost>
  532.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  533. </WindowsFormsHost><WindowsFormsHost>
  534.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  535. </WindowsFormsHost><WindowsFormsHost>
  536.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  537. </WindowsFormsHost>break;<WindowsFormsHost>
  538.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  539. </WindowsFormsHost><WindowsFormsHost>
  540.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  541. </WindowsFormsHost><WindowsFormsHost>
  542.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  543. </WindowsFormsHost><WindowsFormsHost>
  544.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  545. </WindowsFormsHost><WindowsFormsHost>
  546.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  547. </WindowsFormsHost>case DisposalMethod.RestorePrevious:<WindowsFormsHost>
  548.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  549. </WindowsFormsHost><WindowsFormsHost>
  550.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  551. </WindowsFormsHost><WindowsFormsHost>
  552.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  553. </WindowsFormsHost><WindowsFormsHost>
  554.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  555. </WindowsFormsHost><WindowsFormsHost>
  556.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  557. </WindowsFormsHost><WindowsFormsHost>
  558.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  559. </WindowsFormsHost>// 隐藏上一帧<WindowsFormsHost>
  560.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  561. </WindowsFormsHost><WindowsFormsHost>
  562.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  563. </WindowsFormsHost><WindowsFormsHost>
  564.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  565. </WindowsFormsHost><WindowsFormsHost>
  566.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  567. </WindowsFormsHost><WindowsFormsHost>
  568.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  569. </WindowsFormsHost><WindowsFormsHost>
  570.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  571. </WindowsFormsHost>previousInfo.Frame.Visibility = Visibility.Hidden;<WindowsFormsHost>
  572.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  573. </WindowsFormsHost><WindowsFormsHost>
  574.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  575. </WindowsFormsHost><WindowsFormsHost>
  576.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  577. </WindowsFormsHost><WindowsFormsHost>
  578.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  579. </WindowsFormsHost><WindowsFormsHost>
  580.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  581. </WindowsFormsHost><WindowsFormsHost>
  582.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  583. </WindowsFormsHost>break;<WindowsFormsHost>
  584.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  585. </WindowsFormsHost><WindowsFormsHost>
  586.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  587. </WindowsFormsHost><WindowsFormsHost>
  588.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  589. </WindowsFormsHost><WindowsFormsHost>
  590.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  591. </WindowsFormsHost>}<WindowsFormsHost>
  592.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  593. </WindowsFormsHost><WindowsFormsHost>
  594.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  595. </WindowsFormsHost><WindowsFormsHost>
  596.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  597. </WindowsFormsHost>}<WindowsFormsHost>
  598.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  599. </WindowsFormsHost><WindowsFormsHost>
  600.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  601. </WindowsFormsHost><WindowsFormsHost>
  602.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  603. </WindowsFormsHost>else<WindowsFormsHost>
  604.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  605. </WindowsFormsHost><WindowsFormsHost>
  606.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  607. </WindowsFormsHost><WindowsFormsHost>
  608.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  609. </WindowsFormsHost>{<WindowsFormsHost>
  610.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  611. </WindowsFormsHost><WindowsFormsHost>
  612.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  613. </WindowsFormsHost><WindowsFormsHost>
  614.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  615. </WindowsFormsHost><WindowsFormsHost>
  616.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  617. </WindowsFormsHost>// 重新循环, 只显示第一帧<WindowsFormsHost>
  618.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  619. </WindowsFormsHost><WindowsFormsHost>
  620.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  621. </WindowsFormsHost><WindowsFormsHost>
  622.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  623. </WindowsFormsHost><WindowsFormsHost>
  624.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  625. </WindowsFormsHost>for (int i = 1; i < frameInfos.Length; i++)<WindowsFormsHost>
  626.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  627. </WindowsFormsHost><WindowsFormsHost>
  628.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  629. </WindowsFormsHost><WindowsFormsHost>
  630.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  631. </WindowsFormsHost><WindowsFormsHost>
  632.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  633. </WindowsFormsHost>{<WindowsFormsHost>
  634.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  635. </WindowsFormsHost><WindowsFormsHost>
  636.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  637. </WindowsFormsHost><WindowsFormsHost>
  638.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  639. </WindowsFormsHost><WindowsFormsHost>
  640.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  641. </WindowsFormsHost><WindowsFormsHost>
  642.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  643. </WindowsFormsHost>frameInfos[i].Frame.Visibility = Visibility.Hidden;<WindowsFormsHost>
  644.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  645. </WindowsFormsHost><WindowsFormsHost>
  646.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  647. </WindowsFormsHost><WindowsFormsHost>
  648.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  649. </WindowsFormsHost><WindowsFormsHost>
  650.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  651. </WindowsFormsHost>}<WindowsFormsHost>
  652.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  653. </WindowsFormsHost><WindowsFormsHost>
  654.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  655. </WindowsFormsHost><WindowsFormsHost>
  656.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  657. </WindowsFormsHost>}<WindowsFormsHost>
  658.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  659. </WindowsFormsHost><WindowsFormsHost>
  660.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  661. </WindowsFormsHost>}<WindowsFormsHost>
  662.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  663. </WindowsFormsHost>}}
复制代码
使用到的从 URL 获取图像流的方法
  1. using System;using System.IO;using System.IO.Packaging;using System.Net;using System.Threading.Tasks;using System.Windows;public static class ResourceHelper{<WindowsFormsHost>
  2.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  3. </WindowsFormsHost>public static Task GetStream(Uri uri)<WindowsFormsHost>
  4.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  5. </WindowsFormsHost>{<WindowsFormsHost>
  6.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  7. </WindowsFormsHost><WindowsFormsHost>
  8.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  9. </WindowsFormsHost>if (!uri.IsAbsoluteUri)<WindowsFormsHost>
  10.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  11. </WindowsFormsHost><WindowsFormsHost>
  12.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  13. </WindowsFormsHost>{<WindowsFormsHost>
  14.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  15. </WindowsFormsHost><WindowsFormsHost>
  16.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  17. </WindowsFormsHost><WindowsFormsHost>
  18.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  19. </WindowsFormsHost>throw new ArgumentException("uri must be absolute");<WindowsFormsHost>
  20.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  21. </WindowsFormsHost><WindowsFormsHost>
  22.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  23. </WindowsFormsHost>}<WindowsFormsHost>
  24.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  25. </WindowsFormsHost><WindowsFormsHost>
  26.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  27. </WindowsFormsHost>if (uri.Scheme == Uri.UriSchemeHttps<WindowsFormsHost>
  28.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  29. </WindowsFormsHost><WindowsFormsHost>
  30.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  31. </WindowsFormsHost><WindowsFormsHost>
  32.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  33. </WindowsFormsHost>|| uri.Scheme == Uri.UriSchemeHttp<WindowsFormsHost>
  34.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  35. </WindowsFormsHost><WindowsFormsHost>
  36.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  37. </WindowsFormsHost><WindowsFormsHost>
  38.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  39. </WindowsFormsHost>|| uri.Scheme == Uri.UriSchemeFtp)<WindowsFormsHost>
  40.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  41. </WindowsFormsHost><WindowsFormsHost>
  42.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  43. </WindowsFormsHost>{<WindowsFormsHost>
  44.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  45. </WindowsFormsHost><WindowsFormsHost>
  46.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  47. </WindowsFormsHost><WindowsFormsHost>
  48.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  49. </WindowsFormsHost>return Task.Run(() =><WindowsFormsHost>
  50.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  51. </WindowsFormsHost><WindowsFormsHost>
  52.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  53. </WindowsFormsHost><WindowsFormsHost>
  54.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  55. </WindowsFormsHost>{<WindowsFormsHost>
  56.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  57. </WindowsFormsHost><WindowsFormsHost>
  58.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  59. </WindowsFormsHost><WindowsFormsHost>
  60.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  61. </WindowsFormsHost><WindowsFormsHost>
  62.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  63. </WindowsFormsHost>using (var client = new WebClient())<WindowsFormsHost>
  64.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  65. </WindowsFormsHost><WindowsFormsHost>
  66.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  67. </WindowsFormsHost><WindowsFormsHost>
  68.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  69. </WindowsFormsHost><WindowsFormsHost>
  70.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  71. </WindowsFormsHost>{<WindowsFormsHost>
  72.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  73. </WindowsFormsHost><WindowsFormsHost>
  74.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  75. </WindowsFormsHost><WindowsFormsHost>
  76.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  77. </WindowsFormsHost><WindowsFormsHost>
  78.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  79. </WindowsFormsHost><WindowsFormsHost>
  80.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  81. </WindowsFormsHost>byte[] data = client.DownloadData(uri);<WindowsFormsHost>
  82.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  83. </WindowsFormsHost><WindowsFormsHost>
  84.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  85. </WindowsFormsHost><WindowsFormsHost>
  86.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  87. </WindowsFormsHost><WindowsFormsHost>
  88.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  89. </WindowsFormsHost><WindowsFormsHost>
  90.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  91. </WindowsFormsHost>return new MemoryStream(data);<WindowsFormsHost>
  92.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  93. </WindowsFormsHost><WindowsFormsHost>
  94.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  95. </WindowsFormsHost><WindowsFormsHost>
  96.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  97. </WindowsFormsHost><WindowsFormsHost>
  98.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  99. </WindowsFormsHost>}<WindowsFormsHost>
  100.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  101. </WindowsFormsHost><WindowsFormsHost>
  102.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  103. </WindowsFormsHost><WindowsFormsHost>
  104.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  105. </WindowsFormsHost>});<WindowsFormsHost>
  106.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  107. </WindowsFormsHost><WindowsFormsHost>
  108.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  109. </WindowsFormsHost>}<WindowsFormsHost>
  110.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  111. </WindowsFormsHost><WindowsFormsHost>
  112.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  113. </WindowsFormsHost>else if (uri.Scheme == PackUriHelper.UriSchemePack)<WindowsFormsHost>
  114.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  115. </WindowsFormsHost><WindowsFormsHost>
  116.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  117. </WindowsFormsHost>{<WindowsFormsHost>
  118.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  119. </WindowsFormsHost><WindowsFormsHost>
  120.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  121. </WindowsFormsHost><WindowsFormsHost>
  122.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  123. </WindowsFormsHost>var info = uri.Authority == "siteoforigin:,,,"<WindowsFormsHost>
  124.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  125. </WindowsFormsHost><WindowsFormsHost>
  126.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  127. </WindowsFormsHost><WindowsFormsHost>
  128.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  129. </WindowsFormsHost><WindowsFormsHost>
  130.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  131. </WindowsFormsHost>? Application.GetRemoteStream(uri)<WindowsFormsHost>
  132.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  133. </WindowsFormsHost><WindowsFormsHost>
  134.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  135. </WindowsFormsHost><WindowsFormsHost>
  136.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  137. </WindowsFormsHost><WindowsFormsHost>
  138.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  139. </WindowsFormsHost>: Application.GetResourceStream(uri);<WindowsFormsHost>
  140.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  141. </WindowsFormsHost><WindowsFormsHost>
  142.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  143. </WindowsFormsHost><WindowsFormsHost>
  144.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  145. </WindowsFormsHost>if (info != null)<WindowsFormsHost>
  146.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  147. </WindowsFormsHost><WindowsFormsHost>
  148.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  149. </WindowsFormsHost><WindowsFormsHost>
  150.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  151. </WindowsFormsHost>{<WindowsFormsHost>
  152.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  153. </WindowsFormsHost><WindowsFormsHost>
  154.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  155. </WindowsFormsHost><WindowsFormsHost>
  156.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  157. </WindowsFormsHost><WindowsFormsHost>
  158.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  159. </WindowsFormsHost>return Task.FromResult(info.Stream);<WindowsFormsHost>
  160.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  161. </WindowsFormsHost><WindowsFormsHost>
  162.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  163. </WindowsFormsHost><WindowsFormsHost>
  164.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  165. </WindowsFormsHost>}<WindowsFormsHost>
  166.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  167. </WindowsFormsHost><WindowsFormsHost>
  168.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  169. </WindowsFormsHost>}<WindowsFormsHost>
  170.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  171. </WindowsFormsHost><WindowsFormsHost>
  172.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  173. </WindowsFormsHost>else if (uri.Scheme == Uri.UriSchemeFile)<WindowsFormsHost>
  174.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  175. </WindowsFormsHost><WindowsFormsHost>
  176.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  177. </WindowsFormsHost>{<WindowsFormsHost>
  178.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  179. </WindowsFormsHost><WindowsFormsHost>
  180.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  181. </WindowsFormsHost><WindowsFormsHost>
  182.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  183. </WindowsFormsHost>return Task.FromResult(File.OpenRead(uri.LocalPath));<WindowsFormsHost>
  184.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  185. </WindowsFormsHost><WindowsFormsHost>
  186.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  187. </WindowsFormsHost>}<WindowsFormsHost>
  188.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  189. </WindowsFormsHost><WindowsFormsHost>
  190.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  191. </WindowsFormsHost>throw new FileNotFoundException(uri.OriginalString);<WindowsFormsHost>
  192.     <wf:PictureBox x:Name="winFormsPictureBox"/>
  193. </WindowsFormsHost>}}
复制代码
调用示例
  1. [/code][size=5]ImageAnimator[/size]
  2. WinForm 中播放 GIF 用到了 ImageAnimator,利用它也可以在 WPF 中实现 GIF 动图控件,但其是基于 GDI 的方法,更推荐性能更好、支持硬解的解码器方法
  3. [code]using System;
  4. using System.IO;
  5. using System.Text;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Media;
  9. using System.Windows.Media.Animation;
  10. using System.Windows.Media.Imaging;
  11. public sealed class GifImage : ContentControl
  12. {
  13.     /// <summary>当前帧播放完成后的处理方法</summary>
  14.     enum DisposalMethod
  15.     {
  16.         /// <summary>被全尺寸不透明的下一帧覆盖替换</summary>
  17.         None,
  18.         /// <summary>不丢弃, 继续显示下一帧未覆盖的任何像素</summary>
  19.         DoNotDispose,
  20.         /// <summary>重置到背景色</summary>
  21.         RestoreBackground,
  22.         /// <summary>恢复到上一个未释放的帧的状态</summary>
  23.         RestorePrevious,
  24.     }
  25.     sealed class FrameInfo
  26.     {
  27.         public Image Frame { get; }
  28.         public int DelayTime { get; }
  29.         public DisposalMethod DisposalMethod { get; }
  30.         public FrameInfo(BitmapFrame frame)
  31.         {
  32.             Frame = new Image { Source = frame };
  33.             var data = (BitmapMetadata)frame.Metadata;
  34.             DelayTime = Convert.ToUInt16(data.GetQuery("/grctlext/Delay"));
  35.             DisposalMethod = (DisposalMethod)Convert.ToByte(data.GetQuery("/grctlext/Disposal"));
  36.             ushort left = Convert.ToUInt16(data.GetQuery("/imgdesc/Left"));
  37.             ushort top = Convert.ToUInt16(data.GetQuery("/imgdesc/Top"));
  38.             ushort width = Convert.ToUInt16(data.GetQuery("/imgdesc/Width"));
  39.             ushort height = Convert.ToUInt16(data.GetQuery("/imgdesc/Height"));
  40.             Canvas.SetLeft(Frame, left);
  41.             Canvas.SetTop(Frame, top);
  42.             Canvas.SetRight(Frame, left + width);
  43.             Canvas.SetBottom(Frame, top + height);
  44.         }
  45.     }
  46.     public static readonly DependencyProperty UriSourceProperty =
  47.         DependencyProperty.Register(nameof(UriSource), typeof(Uri), typeof(GifImage), new PropertyMetadata(null, OnSourceChanged));
  48.     public static readonly DependencyProperty StreamSourceProperty =
  49.         DependencyProperty.Register(nameof(StreamSource), typeof(Stream), typeof(GifImage), new PropertyMetadata(null, OnSourceChanged));
  50.     public static readonly DependencyProperty FrameIndexProperty =
  51.         DependencyProperty.Register(nameof(FrameIndex), typeof(int), typeof(GifImage), new PropertyMetadata(0, OnFrameIndexChanged));
  52.     public static readonly DependencyProperty StretchProperty =
  53.         DependencyProperty.Register(nameof(Stretch), typeof(Stretch), typeof(GifImage), new PropertyMetadata(Stretch.None, OnStrechChanged));
  54.     public static readonly DependencyProperty StretchDirectionProperty =
  55.         DependencyProperty.Register(nameof(StretchDirection), typeof(StretchDirection), typeof(GifImage), new PropertyMetadata(StretchDirection.Both, OnStrechDirectionChanged));
  56.     public static readonly DependencyProperty IsLoadingProperty =
  57.         DependencyProperty.Register(nameof(IsLoading), typeof(bool), typeof(GifImage), new PropertyMetadata(false));
  58.     public Uri UriSource
  59.     {
  60.         get => (Uri)GetValue(UriSourceProperty);
  61.         set => SetValue(UriSourceProperty, value);
  62.     }
  63.     public Stream StreamSource
  64.     {
  65.         get => (Stream)GetValue(StreamSourceProperty);
  66.         set => SetValue(StreamSourceProperty, value);
  67.     }
  68.     public int FrameIndex
  69.     {
  70.         get => (int)GetValue(FrameIndexProperty);
  71.         private set => SetValue(FrameIndexProperty, value);
  72.     }
  73.     public Stretch Stretch
  74.     {
  75.         get => (Stretch)GetValue(StretchProperty);
  76.         set => SetValue(StretchProperty, value);
  77.     }
  78.     public StretchDirection StretchDirection
  79.     {
  80.         get => (StretchDirection)GetValue(StretchDirectionProperty);
  81.         set => SetValue(StretchDirectionProperty, value);
  82.     }
  83.     public bool IsLoading
  84.     {
  85.         get => (bool)GetValue(IsLoadingProperty);
  86.         set => SetValue(IsLoadingProperty, value);
  87.     }
  88.     private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  89.     {
  90.         ((GifImage)d)?.OnSourceChanged();
  91.     }
  92.     private static void OnFrameIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  93.     {
  94.         ((GifImage)d)?.OnFrameIndexChanged();
  95.     }
  96.     private static void OnStrechChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  97.     {
  98.         if (d is GifImage image && image.Content is Viewbox viewbox)
  99.         {
  100.             viewbox.Stretch = image.Stretch;
  101.         }
  102.     }
  103.     private static void OnStrechDirectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  104.     {
  105.         if (d is GifImage image && image.Content is Viewbox viewbox)
  106.         {
  107.             viewbox.StretchDirection = image.StretchDirection;
  108.         }
  109.     }
  110.     Stream stream;
  111.     Canvas canvas;
  112.     FrameInfo[] frameInfos;
  113.     Int32AnimationUsingKeyFrames animation;
  114.     public GifImage()
  115.     {
  116.         IsVisibleChanged += OnIsVisibleChanged;
  117.         Unloaded += OnUnloaded;
  118.     }
  119.     private void OnUnloaded(object sender, RoutedEventArgs e)
  120.     {
  121.         Release();
  122.     }
  123.     private void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
  124.     {
  125.         if (IsVisible)
  126.         {
  127.             StartAnimation();
  128.         }
  129.         else
  130.         {
  131.             StopAnimation();
  132.         }
  133.     }
  134.     private void StartAnimation()
  135.     {
  136.         BeginAnimation(FrameIndexProperty, animation);
  137.     }
  138.     private void StopAnimation()
  139.     {
  140.         BeginAnimation(FrameIndexProperty, null);
  141.     }
  142.     private void Release()
  143.     {
  144.         StopAnimation();
  145.         canvas?.Children.Clear();
  146.         stream?.Dispose();
  147.         animation = null;
  148.         frameInfos = null;
  149.     }
  150.     private async void OnSourceChanged()
  151.     {
  152.         Release();
  153.         IsLoading = true;
  154.         FrameIndex = 0;
  155.         if (UriSource != null)
  156.         {
  157.             stream = await ResourceHelper.GetStream(UriSource);
  158.         }
  159.         else
  160.         {
  161.             stream = StreamSource;
  162.         }
  163.         if (stream != null)
  164.         {
  165.             int loop = 1;
  166.             bool isAnimated = true;
  167.             var decoder = new GifBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
  168.             var data = decoder.Metadata;
  169.             if (data.GetQuery("/appext/Application") is byte[] array1)
  170.             {
  171.                 string appName = Encoding.ASCII.GetString(array1);
  172.                 if ((appName == "NETSCAPE2.0" || appName == "ANIMEXTS1.0")
  173.                     && data.GetQuery("/appext/Data") is byte[] array2)
  174.                 {
  175.                     loop = array2[2] | array2[3] << 8;// 获取循环次数, 0表示无限循环
  176.                     isAnimated = array2[1] == 1;
  177.                 }
  178.             }
  179.             if (!(Content is Viewbox viewbox))
  180.             {
  181.                 Content = viewbox = new Viewbox
  182.                 {
  183.                     Stretch = Stretch,
  184.                     StretchDirection = StretchDirection,
  185.                 };
  186.             }
  187.             if (canvas == null || canvas.Parent != Content)
  188.             {
  189.                 canvas = new Canvas();
  190.                 viewbox.Child = canvas;
  191.             }
  192.             canvas.Width = Convert.ToUInt16(data.GetQuery("/logscrdesc/Width"));
  193.             canvas.Height = Convert.ToUInt16(data.GetQuery("/logscrdesc/Height"));
  194.             int count = decoder.Frames.Count;
  195.             frameInfos = new FrameInfo[count];
  196.             for (int i = 0; i < count; i++)
  197.             {
  198.                 var info = new FrameInfo(decoder.Frames[i]);
  199.                 Image frame = info.Frame;
  200.                 frameInfos[i] = info;
  201.                 canvas.Children.Add(frame);
  202.                 Panel.SetZIndex(frame, i);
  203.                 canvas.Width = Math.Max(canvas.Width, Canvas.GetRight(frame));
  204.                 canvas.Height = Math.Max(canvas.Height, Canvas.GetBottom(frame));
  205.             }
  206.             OnFrameIndexChanged();
  207.             if (isAnimated)
  208.             {
  209.                 var keyFrames = new Int32KeyFrameCollection();
  210.                 var last = TimeSpan.Zero;
  211.                 for (int i = 0; i < frameInfos.Length; i++)
  212.                 {
  213.                     last += TimeSpan.FromMilliseconds(frameInfos[i].DelayTime * 10);
  214.                     keyFrames.Add(new DiscreteInt32KeyFrame(i, last));
  215.                 }
  216.                 animation = new Int32AnimationUsingKeyFrames
  217.                 {
  218.                     KeyFrames = keyFrames,
  219.                     RepeatBehavior = loop == 0 ? RepeatBehavior.Forever : new RepeatBehavior(loop)
  220.                 };
  221.                 StartAnimation();
  222.             }
  223.         }
  224.         IsLoading = false;
  225.     }
  226.     private void OnFrameIndexChanged()
  227.     {
  228.         if (frameInfos != null)
  229.         {
  230.             int index = FrameIndex;
  231.             frameInfos[index].Frame.Visibility = Visibility.Visible;
  232.             if (index > 0)
  233.             {
  234.                 var previousInfo = frameInfos[index - 1];
  235.                 switch (previousInfo.DisposalMethod)
  236.                 {
  237.                     case DisposalMethod.RestoreBackground:
  238.                         // 隐藏之前的所有帧
  239.                         for (int i = 0; i < index - 1; i++)
  240.                         {
  241.                             frameInfos[i].Frame.Visibility = Visibility.Hidden;
  242.                         }
  243.                         break;
  244.                     case DisposalMethod.RestorePrevious:
  245.                         // 隐藏上一帧
  246.                         previousInfo.Frame.Visibility = Visibility.Hidden;
  247.                         break;
  248.                 }
  249.             }
  250.             else
  251.             {
  252.                 // 重新循环, 只显示第一帧
  253.                 for (int i = 1; i < frameInfos.Length; i++)
  254.                 {
  255.                     frameInfos[i].Frame.Visibility = Visibility.Hidden;
  256.                 }
  257.             }
  258.         }
  259.     }
  260. }
复制代码
透明 GIF

GIF 本身只有 256 色,没有 Alpha 通道,但其仍支持透明,是通过其特殊的自定义颜色表调色盘实现的
1.gif

上图是一张单帧透明 GIF,使用 Windows 自带画图打开,会错误显示为橙色背景
2.png

放入 WinForm PictureBox 中,Win7 和较旧的 Win10 也会错误显示为橙色背景
但最新的 Win11 和 Win10 上会显示为透明背景,猜测是近期 Win11 在截图工具中推出了录制 GIF 功能时顺手更新了 .NET System.Drawing GIF 解析方法,Win10 也收到了这次补丁更新
不过使用 WPF 解码器方法能过获得正确的背景
相关资料

Table of Contents
Native Image Format Metadata Queries - Win32 apps
WICGifGraphicControlExtensionProperties (wincodec.h) - Win32 apps | Microsoft Learn
WICGifImageDescriptorProperties (wincodec.h) - Win32 apps | Microsoft Learn
[WPF疑难]在WPF中显示动态GIF - 周银辉 - 博客园
wpf GifBitmapDecoder 解析 gif 格式
浓缩的才是精华:浅析GIF格式图片的存储和压缩 - 腾讯云开发者 - 博客园

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册