private static CompressedBitmapSource ClearArea(CompressedBitmapSource compFrame, FrameMetadata metadata) { BitmapSource frame = compFrame; DrawingVisual visual = new DrawingVisual(); using (var context = visual.RenderOpen()) { var fullRect = new Rect(0, 0, frame.PixelWidth, frame.PixelHeight); var clearRect = new Rect(metadata.Left, metadata.Top, metadata.Width, metadata.Height); var clip = Geometry.Combine( new RectangleGeometry(fullRect), new RectangleGeometry(clearRect), GeometryCombineMode.Exclude, null); context.PushClip(clip); context.DrawImage(frame, fullRect); } var bitmap = new RenderTargetBitmap( frame.PixelWidth, frame.PixelHeight, frame.DpiX, frame.DpiY, PixelFormats.Pbgra32); bitmap.Render(visual); //if (bitmap.CanFreeze && !bitmap.IsFrozen) // bitmap.Freeze(); var result = new CompressedBitmapSource(bitmap); bitmap = null; return(result); }
private static CompressedBitmapSource MakeFrame( Int32Size fullSize, CompressedBitmapSource rawFrame, FrameMetadata metadata, CompressedBitmapSource baseFrame) { if (baseFrame == null && IsFullFrame(metadata, fullSize)) { // No previous image to combine with, and same size as the full image // Just return the frame as is return(rawFrame); } WriteableBitmap bitmap; if (baseFrame == null) { bitmap = new WriteableBitmap(fullSize.Width, fullSize.Height, 96, 96, PixelFormats.Pbgra32, null); } else { bitmap = new WriteableBitmap(baseFrame); } var rawBitmap = new WriteableBitmap(rawFrame); bitmap.Blit(new Rect(metadata.Left, metadata.Top, metadata.Width, metadata.Height), rawBitmap, new Rect(0, 0, rawFrame.Width, rawFrame.Height)); var result = new CompressedBitmapSource((BitmapSource)bitmap); bitmap = null; rawBitmap = null; GC.Collect(); Dispatcher.CurrentDispatcher.Invoke(() => {}, DispatcherPriority.ContextIdle); return(result); }
private static ObjectAnimationUsingKeyFrames GetAnimation(Image imageControl, BitmapSource source) { var animation = AnimationCache.GetAnimation(source, GetRepeatBehavior(imageControl)); if (animation != null) { return(animation); } 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; animation = new ObjectAnimationUsingKeyFrames(); var totalDuration = TimeSpan.Zero; CompressedBitmapSource baseFrame = null; foreach (var rawFrame in decoder.Frames) { var metadata = GetFrameMetadata(decoder, gifMetadata, index); var result = MakeFrame(fullSize, rawFrame, metadata, baseFrame); var frame = new CompressedBitmapSource(result); 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); AnimationCache.AddAnimation(source, GetRepeatBehavior(imageControl), animation); AnimationCache.IncrementReferenceCount(source, GetRepeatBehavior(imageControl)); return(animation); } return(null); }