7

我正在嘗試顯示存儲在Windows Phone 8.1(RT)應用程序的本地文件夾中的GIF文件。到目前爲止,我已經嘗試了幾種方法:如何在Windows Phone 8.1(RT)應用程序中顯示動畫GIF?

  1. 在WebView控件中加載GIF。這不是一個解決方案,因爲我想在FlipView控件中顯示圖像(我不能翻轉到另一個圖像)。此外,它很慢。
  2. 使用BitmapDecoder類獲取GIF幀,並使用故事板爲它們製作動畫。

    的代碼如下:

using (var stream = await storageFile.OpenReadAsync()) 
    { 
     //I don't specify the type since I would like to load other type of images also 
     //It doesn't make any difference if I would use "BitmapDecoder.GifDecoderId" 

     var decoder = await BitmapDecoder.CreateAsync(stream); 
     uint frameCount = decoder.FrameCount; 

     for (uint frameIndex = 0; frameIndex < frameCount; frameIndex++) 
     { 
      var frame = await decoder.GetFrameAsync(frameIndex); 
      var writableBitmap = new WriteableBitmap((int)decoder.OrientedPixelWidth, 
                (int)decoder.OrientedPixelHeight); 

      var pixelDataProvider = await frame.GetPixelDataAsync 
       (BitmapPixelFormat.Bgra8, 
       decoder.BitmapAlphaMode, new BitmapTransform(), 
       ExifOrientationMode.IgnoreExifOrientation, 
       ColorManagementMode.DoNotColorManage); 

      var pixelData = pixelDataProvider.DetachPixelData(); 
      using (var pixelStream = writableBitmap.PixelBuffer.AsStream()) 
      { 
       pixelStream.Write(pixelData, 0, pixelData.Length); 
      } 

      _bitmapFrames.Add(writableBitmap); 
     } 
    } 

的問題是,我從GIF圖像得到幀搞砸

like this one

我做得不對的這種方法?爲了獲得好的結果,我應該修改什麼?

我不想使用SharpDX,因爲它看起來非常複雜,而且我是初學者。

ImageTools僅適用於Silverlight的

+0

這些日子人們還在使用動畫.gif嗎?我討厭甚至不得不提出保留它,但你可以做'' - 雖然我猜如果你要保留它,讓我知道,我會把它作爲回答,所以我可以拿出一些簡單的點。 :) – 2014-10-02 19:29:18

+1

我已經嘗試添加一個MediaElement到頁面,並設置gif文件作爲其源。在將'AreTransportControlsEnabled'設置爲true後,我可以看到錯誤消息:'不支持的視頻類型或無效的文件路徑'。此外,GIF文件的路徑設置正確。 – rhcpfan 2014-10-03 07:11:14

+0

可能發誓我之前使用過它,也許不是WP?如果我有時間的話,我會稍後修改它。對於那個很抱歉。 – 2014-10-03 12:46:18

回答

6

我做了一個非常基本控制GifImage,您可以從啓動。 這是一個起點,您必須對其進行改進才能使其更可用作可重用控件。檢查一下here

GifImage windows phone screenshot


編輯

你有什麼想法如何提高加載速度(並行等)?

我假設你指的是準備幀的過程。從我測試的結果來看,似乎無論如何都會立即加載,所以不應該需要大幅度的性能改進。但是,如果動畫可能有數百幀,那麼它可能會成爲瓶頸?需要做更多的測試來評估是否需要優化。

我也不認爲它可以很容易並行,因爲每幀需要從前一幀的順序呈現。我唯一的建議是在後臺線程上運行加載代碼,以便UI線程不會阻塞大圖像。

如果我將此控件設置爲FlipViewItem,在物品翻轉後如何釋放內存?

我不知道你是否正在使用MVVM與否,但無論如何,這裏有一些建議:

  • 設置GifImageSource爲null,如果它不是當前可見的(檢查翻轉視圖的SelectedIndex)。請注意,目前我的回購代碼中的代碼不會將Source設置爲空。就像我之前所說的,它需要很多改進。您必須確保控件不包含任何對幀的引用,以便垃圾收集器可以將它們從內存中釋放(也就是,請致電animation.KeyFrames.Clear()以清除對幀的所有引用)。
  • 在翻轉視圖內使用VirtualizingStackPanel。這將確保只在內存中創建前一個,當前和下一個翻轉視圖項目。你這樣設置:
<FlipView> 
    <FlipView.ItemsPanel> 
     <ItemsPanelTemplate> 
      <VirtualizingStackPanel Orientation="Horizontal" /> 
     </ItemsPanelTemplate> 
    </FlipView.ItemsPanel> 
</FlipView> 
+0

謝謝你的解決方案!我只做了小測試,但它工作正常。 你有什麼想法如何提高加載速度(並行化等)? 此外,如果我將此控件作爲FlipViewItem使用,在物品翻轉後如何釋放內存? 再次感謝您的時間! – rhcpfan 2014-10-06 13:53:08

2

我有類似的問題。我試圖顯示一個從Windows Phone 8.1應用程序的ScrollViewer內部的外部源加載的GIF動畫。由於Web控件接管事件,滾動不起作用。

我使用了這個技巧:我將網頁控件放置在網格中,並在網頁控件上放置另一個網格。網頁控件上的網格被設置爲完全相同的大小,我將背景設置爲透明。這樣網格再次接收事件和滾動工作。

<ScrollViewer Visibility="Visible" HorizontalAlignment="Left" VerticalAlignment="Top" Width="380"> 
    <Grid> 
     <StackPanel> 

      <!-- 
      Some items ... 
      --> 

      <Grid > 
       <WebView x:Name="animationWebView" HorizontalAlignment="Left" Height="315" Width="390" Visibility="Visible" /> 
       <Grid Width="390" Height="315" Background="Transparent" /> 
      </Grid> 

      <!-- 
      Some other items ... 
      --> 
     </StackPanel> 
    </Grid> 
</ScrollViewer> 
相關問題