眾所周知,在UWP應用框架中,Image控件是無法播放GIF的圖片,只能顯示靜態圖,這樣的體驗不是特別友好。我在Win8、WP8.1的時候實現過gif播放功能,但是最近發現性能和播放效果都差強人意,大家可以看我的貼吧應用,目前還是用我以前寫的gif控件,一些圖片播放效果並不是很正確,或者內存消耗過高,主要原因是因為只對gif每幀做了簡單的處理。
var frame = await decoder.GetFrameAsync(frameIndex).AsTask(token); var writeableBitmap = new WriteableBitmap((int)decoder.OrientedPixelWidth, (int)decoder.OrientedPixelHeight); BitmapFrame bframe = await decoder.GetFrameAsync(frameIndex).AsTask(token); TimeSpan delay = TimeSpan.Zero; BitmapPropertySet bitmapPropertySet = await bframe.BitmapProperties.GetPropertiesAsync(new List<string>()).AsTask(token); if (bitmapPropertySet != null) { BitmapPropertySet delayPropertySet = await (bitmapPropertySet["/grctlext"].Value as BitmapPropertiesView).GetPropertiesAsync(new List<string> { "/Delay", }); if (delayPropertySet != null) { delay = TimeSpan.FromSeconds(double.Parse(delayPropertySet["/Delay"].Value.ToString()) / 100.0); } } if (delay.Equals(TimeSpan.Zero)) { delay = DefaultDelay; } var bitmapTransform = new BitmapTransform(); var pixelDataProvider = await frame.GetPixelDataAsync(BitmapPixelFormat.Bgra8, decoder.BitmapAlphaMode, bitmapTransform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage); var pixels = pixelDataProvider.DetachPixelData(); using (var bitmapStream = writeableBitmap.PixelBuffer.AsStream()) { bitmapStream.Write(pixels, 0, pixels.Length); }
這段代碼,可以看出解析gif每幀沒有對gif的參數做處理,只處理了delay屬性,也就是每幀的播放間隔(這個播放間隔有個比較吭的地方,如果delay為zero一般來說需要加上100毫秒,用於做間隔,否則gif會播放的過快),但是沒對其他的圖片屬性做處理,導致一些gif樣式錯誤,但是這樣的實現相對來說比較簡單,性能效率什么的會更高,而且能適應大部分的gif播放,所以之前做了一些取舍。
時過境遷,前一段時間知道微軟發布了win2d的圖形加速引擎后,就特別感興趣,看到微軟用win2d實現了gif的播放demo,做了一些研究,將微軟的播放demo做了一些改進,開發了uwp的圖片框架ImageLib.UWP,該項目已經發布到Github中(https://github.com/chenrensong/ImageLib.UWP),同時也在nuget上發布了最新版本,大家可以通過
Install-Package ImageLib.UWP
命令來安裝。
ImageLib.UWP支持幾乎所有的uri格式,借鑒了眾多圖片框架的優勢,支持擴展圖片解析器,這部分大家可以在demo中看到,本文暫時不介紹具體的實現原理,下一次我會和大家詳細介紹,如果在使用中遇到問題,歡迎留言。