예제 #1
0
        private static void AnimatedSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            Image image = o as Image;

            if (image != null)
            {
                ImageSource oldValue = e.OldValue as ImageSource;
                ImageSource newValue = e.NewValue as ImageSource;
                if (oldValue != null)
                {
                    image.Loaded   -= new RoutedEventHandler(ImageBehavior.ImageControlLoaded);
                    image.Unloaded -= new RoutedEventHandler(ImageBehavior.ImageControlUnloaded);
                    AnimationCache.DecrementReferenceCount(oldValue, GetRepeatBehavior(image));
                    ImageAnimationController animationController = GetAnimationController(image);
                    if (animationController != null)
                    {
                        animationController.Dispose();
                    }
                    image.Source = null;
                }
                if (newValue != null)
                {
                    image.Loaded   += new RoutedEventHandler(ImageBehavior.ImageControlLoaded);
                    image.Unloaded += new RoutedEventHandler(ImageBehavior.ImageControlUnloaded);
                    if (image.IsLoaded)
                    {
                        InitAnimationOrImage(image);
                    }
                }
            }
        }
예제 #2
0
        private static void InitAnimationOrImage(Image imageControl)
        {
            ImageAnimationController animationController = GetAnimationController(imageControl);

            if (animationController != null)
            {
                animationController.Dispose();
            }
            SetAnimationController(imageControl, null);
            SetIsAnimationLoaded(imageControl, false);
            BitmapSource source = GetAnimatedSource(imageControl) as BitmapSource;
            bool         animateInDesignMode = GetAnimateInDesignMode(imageControl);
            bool         flag3 = !DesignerProperties.GetIsInDesignMode(imageControl) || animateInDesignMode;
            bool         flag4 = IsLoadingDeferred(source);

            if ((source != null) && (flag3 && !flag4))
            {
                Action action = null;
                if (source.IsDownloading)
                {
                    EventHandler handler = null;
                    handler = delegate(object sender, EventArgs args) {
                        source.DownloadCompleted -= handler;
                        InitAnimationOrImage(imageControl);
                    };
                    source.DownloadCompleted += handler;
                    imageControl.Source       = source;
                    return;
                }
                ObjectAnimationUsingKeyFrames animation = GetAnimation(imageControl, source);
                if (animation != null)
                {
                    if (animation.KeyFrames.Count <= 0)
                    {
                        imageControl.Source = source;
                    }
                    else
                    {
                        if (action == null)
                        {
                            action = () => imageControl.Source = (ImageSource)animation.KeyFrames[0].Value;
                        }
                        TryTwice(action);
                    }
                    animationController = new ImageAnimationController(imageControl, animation, GetAutoStart(imageControl));
                    SetAnimationController(imageControl, animationController);
                    SetIsAnimationLoaded(imageControl, true);
                    imageControl.RaiseEvent(new RoutedEventArgs(AnimationLoadedEvent, imageControl));
                    return;
                }
            }
            imageControl.Source = source;
            if (source != null)
            {
                SetIsAnimationLoaded(imageControl, true);
                imageControl.RaiseEvent(new RoutedEventArgs(AnimationLoadedEvent, imageControl));
            }
        }
예제 #3
0
        private static void ImageControlUnloaded(object sender, RoutedEventArgs e)
        {
            Image image = sender as Image;

            if (image != null)
            {
                ImageSource animatedSource = GetAnimatedSource(image);
                if (animatedSource != null)
                {
                    AnimationCache.DecrementReferenceCount(animatedSource, GetRepeatBehavior(image));
                }
                ImageAnimationController animationController = GetAnimationController(image);
                if (animationController != null)
                {
                    animationController.Dispose();
                }
            }
        }
예제 #4
0
        private static void InitAnimationOrImage(Image imageControl)
        {
            var controller = GetAnimationController(imageControl);

            if (controller != null)
            {
                controller.Dispose();
            }
            SetAnimationController(imageControl, null);
            SetIsAnimationLoaded(imageControl, false);

            BitmapSource source              = GetAnimatedSource(imageControl) as BitmapSource;
            bool         isInDesignMode      = DesignerProperties.GetIsInDesignMode(imageControl);
            bool         animateInDesignMode = GetAnimateInDesignMode(imageControl);
            bool         shouldAnimate       = !isInDesignMode || animateInDesignMode;

            // For a BitmapImage with a relative UriSource, the loading is deferred until
            // BaseUri is set. This method will be called again when BaseUri is set.
            bool isLoadingDeferred = IsLoadingDeferred(source, imageControl);

            if (source != null && shouldAnimate && !isLoadingDeferred)
            {
                // Case of image being downloaded: retry after download is complete
                if (source.IsDownloading)
                {
                    EventHandler handler = null;
                    handler = (sender, args) =>
                    {
                        source.DownloadCompleted -= handler;
                        InitAnimationOrImage(imageControl);
                    };
                    source.DownloadCompleted += handler;
                    imageControl.Source       = source;
                    return;
                }

                var animation = GetAnimation(imageControl, source);
                if (animation != null)
                {
                    if (animation.KeyFrames.Count > 0)
                    {
                        // For some reason, it sometimes throws an exception the first time... the second time it works.
                        TryTwice(() => imageControl.Source = (ImageSource)animation.KeyFrames[0].Value);
                    }
                    else
                    {
                        imageControl.Source = source;
                    }

                    controller = new ImageAnimationController(imageControl, animation, GetAutoStart(imageControl));
                    SetAnimationController(imageControl, controller);
                    SetIsAnimationLoaded(imageControl, true);
                    imageControl.RaiseEvent(new RoutedEventArgs(AnimationLoadedEvent, imageControl));
                    return;
                }
            }
            imageControl.Source = source;
            if (source != null)
            {
                SetIsAnimationLoaded(imageControl, true);
                imageControl.RaiseEvent(new RoutedEventArgs(AnimationLoadedEvent, imageControl));
            }
        }
예제 #5
0
 private static void SetAnimationController(DependencyObject obj, ImageAnimationController value)
 {
     obj.SetValue(AnimationControllerPropertyKey, value);
 }
예제 #6
0
        private static void InitAnimationOrImage(Image imageControl)
        {
            var controller = GetAnimationController(imageControl);

            if (controller != null)
            {
                controller.Dispose();
            }
            SetAnimationController(imageControl, null);

            BitmapSource source              = GetAnimatedSource(imageControl) as BitmapSource;
            bool         isInDesignMode      = DesignerProperties.GetIsInDesignMode(imageControl);
            bool         animateInDesignMode = GetAnimateInDesignMode(imageControl);
            bool         shouldAnimate       = !isInDesignMode || animateInDesignMode;

            // For a BitmapImage with a relative UriSource, the loading is deferred until
            // BaseUri is set. This method will be called again when BaseUri is set.
            bool isLoadingDeferred = IsLoadingDeferred(source);

            if (source != null && shouldAnimate && !isLoadingDeferred)
            {
                // Case of image being downloaded: retry after download is complete
                if (source.IsDownloading)
                {
                    EventHandler handler = null;
                    handler = (sender, args) =>
                    {
                        source.DownloadCompleted -= handler;
                        InitAnimationOrImage(imageControl);
                    };
                    source.DownloadCompleted += handler;
                    imageControl.Source       = source;
                    return;
                }

                GifFile gifMetadata;
                var     decoder = GetDecoder(source, out gifMetadata) as GifBitmapDecoder;
                if (decoder != null && decoder.Frames.Count > 1)
                {
                    var          fullSize      = GetFullSize(decoder, gifMetadata);
                    int          index         = 0;
                    var          animation     = new ObjectAnimationUsingKeyFrames();
                    var          totalDuration = TimeSpan.Zero;
                    BitmapSource baseFrame     = null;
                    foreach (var rawFrame in decoder.Frames)
                    {
                        var metadata = GetFrameMetadata(decoder, gifMetadata, index);

                        var frame    = MakeFrame(fullSize, rawFrame, metadata, baseFrame);
                        var keyFrame = new DiscreteObjectKeyFrame(frame, totalDuration);
                        animation.KeyFrames.Add(keyFrame);

                        totalDuration += metadata.Delay;

                        switch (metadata.DisposalMethod)
                        {
                        case FrameDisposalMethod.None:
                        case FrameDisposalMethod.DoNotDispose:
                            baseFrame = frame;
                            break;

                        case FrameDisposalMethod.RestoreBackground:
                            if (IsFullFrame(metadata, fullSize))
                            {
                                baseFrame = null;
                            }
                            else
                            {
                                baseFrame = ClearArea(frame, metadata);
                            }
                            break;

                        case FrameDisposalMethod.RestorePrevious:
                            // Reuse same base frame
                            break;
                        }

                        index++;
                    }
                    animation.Duration = totalDuration;

                    animation.RepeatBehavior = GetActualRepeatBehavior(imageControl, decoder, gifMetadata);

                    if (animation.KeyFrames.Count > 0)
                    {
                        // For some reason, it sometimes throws an exception the first time... the second time it works.
                        TryTwice(() => imageControl.Source = (ImageSource)animation.KeyFrames[0].Value);
                    }
                    else
                    {
                        imageControl.Source = decoder.Frames[0];
                    }

                    controller = new ImageAnimationController(imageControl, animation, GetAutoStart(imageControl));
                    SetAnimationController(imageControl, controller);

                    return;
                }
            }
            imageControl.Source = source;
        }