Formular una preguntaFormular una pregunta
 

RespondidaHow to use an animated gif?

  • martes, 28 de marzo de 2006 0:04Derek Ju Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    I was wondering if there was a way to play an animated gif?  I tried setting the source of an image to a gif file but it only loads the first frame of the gif and that's it.

Respuestas

  • martes, 28 de marzo de 2006 6:39R Go Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respondida

    Unfortunately for V1, we have not automatic way of animating a GIF. This is something we are looking at fixing for the next version.

    One workaround would be animate the different frames manually.

  • martes, 28 de marzo de 2006 18:27Rahul Patil [MSFT] Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respondida

    Another really simple workaround is to use MediaElement, and set the source of the MediaElement to the gif file.

        <MediaElement Source="animated.gif"/>

     

    -Thanks

    Rahul Patil

Todas las respuestas

  • martes, 28 de marzo de 2006 6:39R Go Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respondida

    Unfortunately for V1, we have not automatic way of animating a GIF. This is something we are looking at fixing for the next version.

    One workaround would be animate the different frames manually.

  • martes, 28 de marzo de 2006 16:54Derek Ju Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    Hm, ok.  Do you have any suggestions on how I can go about animating manually?
  • martes, 28 de marzo de 2006 18:27Rahul Patil [MSFT] Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respondida

    Another really simple workaround is to use MediaElement, and set the source of the MediaElement to the gif file.

        <MediaElement Source="animated.gif"/>

     

    -Thanks

    Rahul Patil

  • miércoles, 29 de marzo de 2006 22:09chongqing Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    Have anyone tried this?

    It seems mediaElement won't show animated gif either.

    this is my code.

    <MediaElement x:Name="loadingGif" Width="50" Height="100" Source="pack://siteoforigin:,,,/images/loading.gif" HorizontalAlignment="Center"></MediaElement>

    thanks/chong

  • miércoles, 29 de marzo de 2006 22:51Dennis Cheng - MSFT Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    The MediaElement doesn't support the pack:// scheme yet. Try a relative or absolute URI such as http:// or file://. It downloads and plays the GIF just fine.

  • sábado, 01 de abril de 2006 0:01Derek Ju Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    For some reason I still cannot get this to work :(.

    Here is all I am doing:

    <MediaElement Source="animation.gif">

    I have the animation.gif as an item in my project.  When I load up my Window however, I just see a blank space.  The link is correct because if I switch MediaElement with Image I see the first frame of my gif.

  • sábado, 01 de abril de 2006 0:12Dennis Cheng - MSFT Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    That relative path is shorthand for "pack://application:,,,/animation.gif" which doesn't work. The best way to refer to media today is to use an absolute URI to a loose file outside of the project.
  • domingo, 02 de abril de 2006 4:31csammis Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    I'm using a MediaElement to animate a GIF successfully, in this way:

    <MediaElement LoadedBehavior="Play" Source="file://C:/anim.gif" />

    However, when the GIF has transparency, the MediaElement shows black in the areas that should be transparent...ostensibly, the transparent areas of the GIF would show the underlying control.  How can I change this?

    Also, I don't really like the idea of using a MediaElement for the task of animating small GIFs, such as animating emoticons for use in an IM application.  I feel that it's way too heavy an object to create and destroy frequently.  Does anyone have details on the frame-by-frame animation method?

  • domingo, 02 de abril de 2006 17:09Jared Bienz Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    This article shows you how to enumerate through each frame in the animated gif file and obtain them as System.Drawing.Bitmap instances:

    http://www.eggheadcafe.com/articles/stripimagefromanimatedgif.asp

    This thread shows how to convert a System.Drawing.Bitmap into a BitmapSource, which can be displayed in the WPF Image control:

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=320846&SiteID=1

    I would think you could leverage this to create a user control based on the WPF Image control and a timer. The only thing I'm not sure of is how to determine how long you should pause between each frame. That information is of course stored in the gif file, but I'm not sure if you can obtain it through .Net.

    Unfortunately, I don't really have an idea how slow this would be. I'd venture to guess that the conversion of a Drawing.Bitmap to BitmapSource is a fairly costly process. You would probably want to convert all frames of the gif to BitmapSources as you load the gif file, and then cache them so you don't have to convert on each frame draw.

    Hope that helps...

    Jared

  • lunes, 23 de octubre de 2006 10:50d00d Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    Has the support for animated GIFs using Image been provided in the latest versions of WPF?
  • martes, 28 de noviembre de 2006 21:07NewYoda Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    I'd also like to use animated GIFs.
    I tried:
    <Grid>
            <MediaElement Source="D:\Animation.gif" />
    </Grid>
    However, my Window is blank. I also tried to use Width and Height properties, but that didn't solve my problem.
  • jueves, 30 de noviembre de 2006 17:17Robert A. WlodarczykMSFT, ModeradorMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    Image element does not support Animated GIFs in this version. Some people have had luck using the MediaElement for Animated GIFs, but no guarantee is made about this solution.
  • lunes, 26 de marzo de 2007 21:31Rob Reiss Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    As a learning project I created a WPF control to display animated GIF files.  The "ImageAnim" control mimics most of the behavior of Microsoft's WPF "Image" control with the additional benefit of handling animated GIF's.  You can download ImageAnim.dll from www.robreiss.com. (its free)

    Rob Reiss

  • lunes, 12 de mayo de 2008 12:21indrajit chavan Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    Hi All,

    For me giving file:// source to mediaelement is also not working.so i opted for http as follows


    Code Snippet
        <MediaElement Source="http://192.168.2.41/it/spinner_48.gif" x:Name="me" LoadedBehavior="Play" ToolTip="Loading..." Canvas.Top="50" UnloadedBehavior="Play" MediaFailed="me_MediaFailed"></MediaElement>
            <TextBlock x:Name="txtError"></TextBlock>

           

     

    but strange thing is it works in IE7 and fails in IE6. for IE6 it raises Mediafailed event and the exception is

    Code Snippet

    "media failed. system.windows.media.invalidwmpversionexception:Windows media player 10 or later is required--->system.runtime.interopservices.comexception(0x88989507).Exception from HRESULT(0x88989507)

    -------------------End of innerexception stack trace-------------------------"

     

     

    Above exception is caught in mediafailed event as follows:

     

    Code Snippet

    private void me_MediaFailed(object sender, ExceptionRoutedEventArgs e)
            {

                txtError.Text = "media failed " + e.ErrorException.ToString();
            }

     

     

    I agree that my client machine has windows media player 9 but how can need of WMP 10 be justified for a simple animated gif? How can i ask my client to take ie7 not ie6 and WMP 10 not 9 just for RICH UX web site(mostly containing animated gif) without video ?It really is going to embrace me

     

     

  • lunes, 19 de mayo de 2008 14:39olayaida Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    There is a better and easier way to animate a GIF. try using winforms PictureBox with the WindowsFormsHost element.
    The code will looks like

    <Window x:Class="Wing.TeleGYM.Client.Controls.StartupScreen"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wfi="clr-namespaceTongue Tiedystem.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
        xmlns:winForms="clr-namespaceTongue Tiedystem.Windows.Forms;assembly=System.Windows.Forms"
        Loaded="Window_Loaded" >

                <DockPanel ... >
                   
                    <wfi:WindowsFormsHost HorizontalAlignment="Center">
                        <winFormsStick out tongueictureBox x:Name="pictureBoxLoading" Width="320" Height="20" ></winFormsStick out tongueictureBox>
                    </wfi:WindowsFormsHost>
                </DockPanel >

    </Window >

    In the Window_Loaded function add the following line of code

    pictureBoxLoading.Image = Properties.Resources.StartUp_Loading; // From resources

    or

    pictureBoxLoading.Image = c:\loading.gif // from dis

    hope this will help
  • miércoles, 04 de junio de 2008 6:03Sergey Ukraine Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respuesta propuesta
    To solve the problem with playing animated GIFs I have created control derived from System.Windows.Controls.Image. This control uses System.Drawing.ImageAnimator class for animating GIF. The main functionality of class is the following:

    using System;
    using System.Drawing;
    using System.Windows;
    using System.Windows.Interop;
    using System.Windows.Threading;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using IpmPlayerLogWriter;

    public class GIFImageControl : System.Windows.Controls.Image
    {
        delegate void OnFrameChangedDelegate();  
        private Bitmap _Bitmap;

        public AnimatedImageControl(string path)
        {
                _Bitmap = (Bitmap)Bitmap.FromFile(path);
                ImageAnimator.Animate(_Bitmap, new EventHandler(OnFrameChanged));
        }


        private void OnFrameChanged(object sender, EventArgs e)
        {
            Dispatcher.BeginInvoke(DispatcherPriority.Normal,
                new OnFrameChangedDelegate(OnFrameChangedInMainThread));
        }

        private void OnFrameChangedInMainThread()
        {
            ImageAnimator.UpdateFrames(_Bitmap);
            this.Source = this.GetBitmapSource(_Bitmap);
            InvalidateVisual();
        }

        private BitmapSource GetBitmapSource(Bitmap gdiBitmap)
        {
            return Imaging.CreateBitmapSourceFromHBitmap(
                gdiBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
        }
    }

    Hope that it helps :)
    • Propuesto como respuestaSergey Ukraine viernes, 06 de junio de 2008 14:42
    •  
  • miércoles, 04 de junio de 2008 7:18Sergey Ukraine Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respuesta propuesta
    I have found one problem in the code I have posted above. Method GetBitmapSource gives memory leak and then GDI crashes. It is better be changed that way:

        [DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
        public static extern IntPtr DeleteObject(IntPtr hDc);

        private BitmapSource GetBitmapSource(Bitmap gdiBitmap)
        {
                IntPtr hBitmap = gdiBitmap.GetHbitmap();
                bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(hBitmap,
                                                                     IntPtr.Zero,
                                                                     Int32Rect.Empty,
                                                                     BitmapSizeOptions.FromEmptyOptions());
                DeleteObject(hBitmap);
        }


    • Propuesto como respuestaSergey Ukraine viernes, 06 de junio de 2008 14:43
    •  
  • viernes, 20 de marzo de 2009 22:06Greg Wilson Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    This thread is great.  I used Sergey Ukraine's info here and made a downloadable control that will display animated .gif from either the filesystem, or from an embedded resource in the assembly.  Additionally, I added the functionality to Play/Pause the animation by clicking on the .gif.  (On by default, but can be turned off with AllowClickToPause to false.)

    I posted the code on my blog, where the whole downloadable project can be downloaded.


    The Pragmatic TSQL Programmer
  • viernes, 17 de julio de 2009 14:02jesus romero Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respuesta propuesta

    Hi

    I had the same problem, so I created a new control, deriving it from the Image class, and applying an animation to the image with a dependency property called FrameIndex. I guess that the frame rate is 10 frames per second.

    This control works well when you are adding the control manually to a container. Some modifications are be required to use it from XAML (using a parameterless constructor).

    The control accepts any URI (I tried with packed URIs) in the constructor.

    class GifImage : Image {

        public int FrameIndex {
            get { return (int)GetValue(FrameIndexProperty); }
            set { SetValue(FrameIndexProperty, value); }
        }

        public static readonly DependencyProperty FrameIndexProperty =
            DependencyProperty.Register("FrameIndex", typeof(int), typeof(GifImage), new UIPropertyMetadata(0, new PropertyChangedCallback(ChangingFrameIndex)));

        static void ChangingFrameIndex(DependencyObject obj, DependencyPropertyChangedEventArgs ev) {
            GifImage ob = obj as GifImage;
            ob.Source = ob.gf.Frames[(int)ev.NewValue];
            ob.InvalidateVisual();
        }
        GifBitmapDecoder gf;
        Int32Animation anim ;           
        public GifImage(Uri uri) {
            gf = new GifBitmapDecoder(uri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            anim = new Int32Animation(0, gf.Frames.Count - 1, new Duration(new TimeSpan(0,0, 0,gf.Frames.Count/10,(int)((gf.Frames.Count/10.0-gf.Frames.Count/10)*1000))));
            anim.RepeatBehavior = RepeatBehavior.Forever;
            Source = gf.Frames[0];
        }
        bool animationIsWorking = false;
        protected override void OnRender(DrawingContext dc) {
            base.OnRender(dc);
            if (!animationIsWorking) {
                BeginAnimation(FrameIndexProperty, anim);
                animationIsWorking = true;
            }
        }
    }

    • Propuesto como respuestaptkdb jueves, 20 de agosto de 2009 14:05
    •  
  • jueves, 20 de agosto de 2009 13:59ptkdb Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    Works nicely...   Thanks for this. 

       Had some very marginal success using a MediaElement but the playback was horrid and drilling through the myriad of properties, clocks, storyboards, triggers, speedratios, repeatbehavior was getting more and more frustrating just to animate a 16x16 icon.

      I think this is about as straightforward as is possible for a simple animation in WPF. 

    Only tweek I had to make was to apply "Stretch=Stretch.None" to keep the image at its original size when I used it as content in a button.

    • Editadoptkdb jueves, 20 de agosto de 2009 14:05felt it needed embellishment
    •  
  • miércoles, 09 de septiembre de 2009 13:03jlspublic Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Tiene código
    Jesus,

    I like your approach since it doesn't require the image format to be retranslated from an HBitmap for every frame display the way Sergey and Greg's did.  I implemented a variation that can be used from XAML and that hides a little more of the implementation from the caller (by not having an exposed FrameIndex property).  I no habla C# so my version is in VB:

    Imports System.Drawing
    Imports System.Threading
    Imports Image = System.Windows.Controls.Image
    
    Public Class AnimatedGIFViewer
        Inherits Image
    
        Private _GIFDecoder As GifBitmapDecoder
        Private _FrameTimer As Timer
        Private _ShowingFrame As Boolean = False
        Private _FrameIndex As Integer
    
        Public Property GIFSource() As Uri
            Get
                Return DirectCast(GetValue(GIFSourceProperty), Uri)
            End Get
    
            Set(ByVal value As Uri)
                SetValue(GIFSourceProperty, value)
            End Set
        End Property
    
        Public Shared ReadOnly GIFSourceProperty As DependencyProperty = _
            DependencyProperty.Register( _
                "GIFSource" _
                , GetType(Uri) _
                , GetType(AnimatedGIFViewer) _
                , New FrameworkPropertyMetadata(Nothing, AddressOf GIFSource_Changed) _
            )
    
        Private Shared Sub GIFSource_Changed(ByVal sender As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
            DirectCast(sender, AnimatedGIFViewer).GIFSourceSet()
        End Sub
    
        Private Sub GIFSourceSet()
            KillCurrentTimer()
    
            If IsNothing(GIFSource) Then
                _GIFDecoder = Nothing
            Else
                _GIFDecoder = New GifBitmapDecoder(GIFSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default)
                _FrameIndex = 0
                _FrameTimer = New Timer(AddressOf ShowFrame, Nothing, 200, 200)
            End If
        End Sub
    
        Private Sub ShowFrame(ByVal State As Object)
    
            'Avoid getting flooded 
            'with event calls since
            'the timer doesn't pay
            'any attention to whether
            'we are keeping up or not.
            If _ShowingFrame Then
                Exit Sub
            End If
    
            _ShowingFrame = True
            Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, New Action(AddressOf OnFrameChanged))
            _ShowingFrame = False
        End Sub
    
        Private Sub OnFrameChanged()
            Source = _GIFDecoder.Frames(_FrameIndex)
            _FrameIndex += 1
    
            If (_FrameIndex = _GIFDecoder.Frames.Count) Then
                _FrameIndex = 0
            End If
    
        End Sub
    
        Private Sub KillCurrentTimer()
    
            If (Not IsNothing(_FrameTimer)) Then
                Dim FrameTimerDisposed As New AutoResetEvent(False)
                _FrameTimer.Dispose(FrameTimerDisposed)
                'In order to ensure that we don't have
                'two timers going at once, we will wait
                'for the dispose to complete but only 
                'for up to 1 second.
                FrameTimerDisposed.WaitOne(1000)
                _ShowingFrame = False
                _FrameTimer = Nothing
            End If
    
        End Sub
    
        Private Sub AnimatedGIFViewer_Unloaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Unloaded
            KillCurrentTimer()
        End Sub
    
    End Class
    
    

    You can use it XAML as follows:

            <local:AnimatedGIFViewer 
                Height="130" 
                Width="156" 
                x:Name="Image1" 
                Stretch="None" 
    GIFSource="pack://application:,,,/MyProject;component/MyGif.gif"
             />
    
    


    -JLS
  • lunes, 21 de septiembre de 2009 15:44msp.netdev Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    Thanks, this solution works fine, but how is possible that microsoft don't fix mediaElement control problem !?
  • martes, 13 de octubre de 2009 16:06Giuseppe Ugo Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    I would really hope Microsoft supports animated GIF directly in Image