public void GetAnimator(ObjectAnimationUsingKeyFrames animator, string path) { var decoder = new APNGBitmap(path); if (decoder.IsSimplePNG) { animator.KeyFrames.Add( new DiscreteObjectKeyFrame(BitmapFrame.Create(new Uri(path)), TimeSpan.Zero)); animator.Duration = Duration.Forever; return; } var clock = TimeSpan.Zero; var header = decoder.IHDRChunk; Frame prevFrame = null; BitmapSource prevRenderedFrame = null; foreach (var rawFrame in decoder.Frames) { var frame = MakeFrame(header, rawFrame, prevFrame, prevRenderedFrame); prevFrame = rawFrame; prevRenderedFrame = frame; var delay = TimeSpan.FromSeconds( (double)rawFrame.fcTLChunk.DelayNum / (rawFrame.fcTLChunk.DelayDen == 0 ? 100 : rawFrame.fcTLChunk.DelayDen)); animator.KeyFrames.Add(new DiscreteObjectKeyFrame(frame, clock)); clock += delay; } animator.Duration = clock; animator.RepeatBehavior = RepeatBehavior.Forever; }
public APNGAnimationProvider(string path, Dispatcher uiDispatcher) : base(path, uiDispatcher) { var decoder = new APNGBitmap(path); if (decoder.IsSimplePNG) { _imageMagickProvider = new ImageMagickProvider(path, uiDispatcher); return; } _frames = new List <FrameInfo>(decoder.Frames.Length); _renderedFrames = new List <BitmapSource>(decoder.Frames.Length); Enumerable.Repeat(0, decoder.Frames.Length).ForEach(_ => _renderedFrames.Add(null)); Animator = new Int32AnimationUsingKeyFrames { RepeatBehavior = RepeatBehavior.Forever }; var wallclock = TimeSpan.Zero; for (var i = 0; i < decoder.Frames.Length; i++) { var frame = decoder.Frames[i]; _frames.Add(new FrameInfo(decoder.IHDRChunk, frame)); Animator.KeyFrames.Add(new DiscreteInt32KeyFrame(i, KeyTime.FromTimeSpan(wallclock))); wallclock += _frames[i].Delay; } }
public APngProvider(Uri path, MetaProvider meta) : base(path, meta) { if (!IsAnimatedPng(path.LocalPath)) { _nativeImageProvider = new NativeProvider(path, meta); Animator = _nativeImageProvider.Animator; return; } var decoder = new APNGBitmap(path.LocalPath); _baseFrame = decoder.DefaultImage; _frames = new List <FrameInfo>(decoder.Frames.Length); _renderedFrames = new List <BitmapSource>(decoder.Frames.Length); Enumerable.Repeat(0, decoder.Frames.Length).ForEach(_ => _renderedFrames.Add(null)); Animator = new Int32AnimationUsingKeyFrames { RepeatBehavior = RepeatBehavior.Forever }; var wallclock = TimeSpan.Zero; for (var i = 0; i < decoder.Frames.Length; i++) { var frame = decoder.Frames[i]; _frames.Add(new FrameInfo(decoder.IHDRChunk, frame)); Animator.KeyFrames.Add(new DiscreteInt32KeyFrame(i, KeyTime.FromTimeSpan(wallclock))); wallclock += _frames[i].Delay; } }
public void GetAnimator(ObjectAnimationUsingKeyFrames animator, string path) { var decoder = new APNGBitmap(path); if (decoder.IsSimplePNG) { new ImageMagickProvider().GetAnimator(animator, path); return; } var clock = TimeSpan.Zero; var header = decoder.IHDRChunk; Frame currentFrame = null; BitmapSource currentRenderedFrame = null; BitmapSource previousStateRenderedFrame = null; foreach (var nextFrame in decoder.Frames) { var nextRenderedFrame = MakeNextFrame(header, nextFrame, currentFrame, currentRenderedFrame, previousStateRenderedFrame); var delay = TimeSpan.FromSeconds( (double)nextFrame.fcTLChunk.DelayNum / (nextFrame.fcTLChunk.DelayDen == 0 ? 100 : nextFrame.fcTLChunk.DelayDen)); animator.KeyFrames.Add(new DiscreteObjectKeyFrame(nextRenderedFrame, clock)); clock += delay; // the "previous state" of a "DisposeOpPrevious" frame is its previous frame, so we do not record it if (currentFrame != null && currentFrame.fcTLChunk.DisposeOp != DisposeOps.APNGDisposeOpPrevious) { previousStateRenderedFrame = currentRenderedFrame; } currentRenderedFrame = nextRenderedFrame; currentFrame = nextFrame; } animator.Duration = clock; animator.RepeatBehavior = RepeatBehavior.Forever; }