示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }