7

Ich versuche, eine GIF-Datei in einem Windows Phone 8.1 (RT) Anwendung lokalen Ordner anzuzeigen. Bis jetzt habe ich mehrere Ansätze ausprobiert:Wie wird ein animiertes GIF in einer Windows Phone 8.1 (RT) -Anwendung angezeigt?

  1. Laden Sie die GIF in einem WebView-Steuerelement. Dies ist keine Lösung, da ich die Bilder in einem FlipView-Steuerelement anzeigen möchte (ich kann nicht zu einem anderen Bild wechseln). Außerdem ist es ziemlich langsam.
  2. Rufen Sie die GIF-Frames mit der BitmapDecoder-Klasse ab und animieren Sie sie mithilfe eines Storyboards.

    Der Code ist wie folgt:

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); 
     } 
    } 

Das Problem ist, dass der Rahmen I aus dem GIF-Bild erhalten wird

verkorkst

like this one

Mache ich etwas falsch in dieser Ansatz? Was muss ich ändern, um gute Ergebnisse zu erzielen?

Ich möchte SharpDX nicht verwenden, da es sehr kompliziert zu sein scheint und ich ein Anfänger bin.

Imagetools ist nur für Silverlight

+0

Die Leute benutzen heute noch animierte .gif? Ich hasse es sogar, vorzuschlagen, es zu behalten, aber du könntest einfach '' MediaElement Source = "YourAnimated.gif" /> '- Obwohl ich denke, wenn du es behalten willst, lass es mich wissen und ich werde das als Antwort, damit ich ein paar einfache Punkte einholen kann. :) –

+1

Ich habe versucht, ein MediaElement zu der Seite hinzuzufügen und die gif-Datei als Quelle festzulegen. Nachdem ich "AreTransportControlsEnabled" auf "true" gesetzt habe, konnte der Fehler "Nicht unterstützter Videotyp oder ungültiger Dateipfad" angezeigt werden. Außerdem wurde der Pfad zur GIF-Datei korrekt festgelegt. – rhcpfan

+0

Ich hätte schwören können, dass ich es vorher benutzt habe, vielleicht war es nicht WP? Ich werde später daran basteln, wenn ich Zeit habe. Das tut mir leid. –

Antwort

6

ich sehr Grund GifImage Kontrolle gemacht, die Sie aus starten können. Dies ist ein Ausgangspunkt, Sie müssen es verbessern, um es als wiederverwendbares Steuerelement nutzbar zu machen. Schau es dir an here.

GifImage windows phone screenshot


EDIT

Haben Sie eine Ahnung, wie die Ladegeschwindigkeit zu verbessern (Parallelisierung, etc.)?

Ich nehme an, Sie beziehen sich auf den Prozess der Vorbereitung der Frames. Von dem, was ich getestet habe, scheint es sofort zu laden, also sollte es keine drastischen Leistungsverbesserungen geben. Wenn die Animation jedoch hunderte von Frames hat, könnte das ein Engpass sein? Es müssen weitere Tests durchgeführt werden, um zu beurteilen, ob Optimierungen notwendig sind oder nicht.

Ich glaube auch nicht, dass es leicht parallelisiert werden kann, da jedes Bild in der Reihenfolge vom vorherigen Bild gerendert werden muss. Mein einziger Vorschlag wäre, den Ladecode auf einem Hintergrund-Thread auszuführen, damit der UI-Thread für große Bilder nicht blockiert wird.

Wenn ich dieses Steuerelement als FlipViewItem habe, wie kann ich den Speicher freigeben, nachdem das Element weggedreht wurde?

Ich bin nicht sicher, ob Sie verwenden MVVM oder nicht, aber wie auch immer, hier einige Vorschläge:

  • Stellen Sie die Source des GifImage auf null, wenn es derzeit nicht sichtbar ist (inspizieren die SelectedIndex der Flip-Ansicht). Beachten Sie, dass der Code in meinem Repo derzeit nicht die Einstellung Source auf null behandelt. Wie ich schon sagte, es braucht viele Verbesserungen. Sie müssen sicherstellen, dass das Steuerelement keine Verweise auf die Frames enthält, sodass der Garbage Collector sie aus dem Speicher freigeben kann (dh, rufen Sie animation.KeyFrames.Clear() auf, um alle Verweise auf die Frames zu löschen).
  • Verwenden Sie eine VirtualizingStackPanel innerhalb der Flip-Ansicht. Dadurch wird sichergestellt, dass nur die vorherigen, aktuellen und nächsten Elemente der Spiegelansicht im Speicher erstellt werden. Sie legen es wie folgt aus:
<FlipView> 
    <FlipView.ItemsPanel> 
     <ItemsPanelTemplate> 
      <VirtualizingStackPanel Orientation="Horizontal" /> 
     </ItemsPanelTemplate> 
    </FlipView.ItemsPanel> 
</FlipView> 
+0

Vielen Dank für Ihre Lösung! Ich habe nur kleine Tests gemacht, aber es funktioniert gut. Haben Sie eine Idee, wie Sie die Ladegeschwindigkeit (Parallelisierung, etc.) verbessern können? Wenn ich dieses Steuerelement als FlipViewItem habe, wie kann ich dann den Speicher freigeben, nachdem das Element weggedreht wurde? Nochmals vielen Dank für Ihre Zeit! – rhcpfan

2

Ich hatte ein ähnliches Problem. Ich habe versucht, ein animiertes GIF anzuzeigen, das von einer externen Quelle in einer ScrollViewer für Windows Phone 8.1 App geladen wurde. Da die Websteuerung die Ereignisse übernimmt, hat das Scrollen nicht funktioniert.

Ich benutzte diesen Trick: Ich legte die Web-Steuerung in ein Raster und legte ein weiteres Raster über das Webcontrol. Das Raster über dem Web-Steuerelement wurde auf genau die gleiche Größe festgelegt und ich setze den Hintergrund transparent. Auf diese Weise erhält das Gitter die Ereignisse und das Scrollen funktioniert wieder.

<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> 
Verwandte Themen