Example #1
0
        private static ObjectAnimationUsingKeyFrames?GetAnimation(Image imageControl, BitmapSource source)
        {
            var animation = AnimationCache.GetAnimation(source, GetRepeatBehavior(imageControl));

            if (animation != null)
            {
                return(animation);
            }
            if (!(GetDecoder(source, imageControl, out var gifMetadata) is GifBitmapDecoder decoder) || decoder.Frames.Count <= 1)
            {
                return(null);
            }

            var fullSize = GetFullSize(decoder, gifMetadata);
            var index    = 0;

            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:
                    baseFrame = IsFullFrame(metadata, fullSize) ? null : ClearArea(frame, metadata);
                    break;

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

                default:
                    throw new ArgumentOutOfRangeException();
                }

                index++;
            }
            animation.Duration = totalDuration;

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

            AnimationCache.AddAnimation(source, GetRepeatBehavior(imageControl), animation);
            AnimationCache.IncrementReferenceCount(source, GetRepeatBehavior(imageControl));
            return(animation);
        }
Example #2
0
        static void ImageControlUnloaded(object sender, RoutedEventArgs e)
        {
            if (!(sender is Image imageControl))
            {
                return;
            }
            var source = GetAnimatedSource(imageControl);

            if (source != null)
            {
                AnimationCache.DecrementReferenceCount(source, GetRepeatBehavior(imageControl));
            }
            var controller = GetAnimationController(imageControl);

            controller?.Dispose();
        }
Example #3
0
        private static void AnimatedSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            if (!(o is Image imageControl))
            {
                return;
            }

            var oldValue = e.OldValue as ImageSource;
            var newValue = e.NewValue as ImageSource;

            if (ReferenceEquals(oldValue, newValue))
            {
                if (imageControl.IsLoaded)
                {
                    var isAnimLoaded = GetIsAnimationLoaded(imageControl);
                    if (!isAnimLoaded)
                    {
                        InitAnimationOrImage(imageControl);
                    }
                }
                return;
            }
            if (oldValue != null)
            {
                imageControl.Loaded   -= ImageControlLoaded;
                imageControl.Unloaded -= ImageControlUnloaded;
                AnimationCache.DecrementReferenceCount(oldValue, GetRepeatBehavior(imageControl));
                var controller = GetAnimationController(imageControl);
                controller?.Dispose();
                imageControl.Source = null;
            }

            if (newValue == null)
            {
                return;
            }

            imageControl.Loaded   += ImageControlLoaded;
            imageControl.Unloaded += ImageControlUnloaded;
            if (imageControl.IsLoaded)
            {
                InitAnimationOrImage(imageControl);
            }
        }
Example #4
0
        private static void RepeatBehaviorChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            if (!(o is Image imageControl))
            {
                return;
            }

            var source = GetAnimatedSource(imageControl);

            if (source == null)
            {
                return;
            }

            if (!Equals(e.OldValue, e.NewValue))
            {
                AnimationCache.DecrementReferenceCount(source, (RepeatBehavior)e.OldValue);
            }
            if (imageControl.IsLoaded)
            {
                InitAnimationOrImage(imageControl);
            }
        }