Taking snapshots of WPF animation


I've been playing around with WPF animation, and ended up wanting to take a snapshot of an animation at a specific place.


Specifically, I have a canvas that has some pictures on it that are moving, and I want to be able to save a bitmap of what it looks like at a specific time.


Getting the bitmap is pretty easy, using a RenderTargetBitmap and a VisualBrush.


private BitmapSource CaptureScreen(Visual target)
{


    Rect bounds = VisualTreeHelper.GetDescendantBounds(target);


    RenderTargetBitmap renderBitmap = new RenderTargetBitmap(800, 600, 96, 96, PixelFormats.Pbgra32);


    DrawingVisual dv = new DrawingVisual();
   
using (DrawingContext ctx = dv.RenderOpen())
    {
        
VisualBrush vb = new VisualBrush(target);


        ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
    }
    renderBitmap.Render(dv);


    return renderBitmap;
}


That gives you the state of the objects pre-animation, but what I really wanted was the state of the objects during the animation. I had some code to move the image around:


    DoubleAnimation anim = new DoubleAnimation(50, 400, TimeSpan.FromSeconds(10), FillBehavior.HoldEnd);
    AnimationClock clock = anim.CreateClock();
    m_imageLeft.ApplyAnimationClock(
Canvas.LeftProperty, clock);


After a bit of research, I settled on the following bit of code to set the animation to the point that I wanted:


    clock.Controller.SeekAlignedToLastTick(TimeSpan.FromSeconds(5.0), TimeSeekOrigin.BeginTime);


Which should have worked fine, but didn't. When I looked at the properties, I noticed that the Left property was changing, but it wasn't showing up. It was almost as if the Canvas didn't know that the object property had changed and a re-layout was necessary...


    m_canvas.UpdateLayout();


was the magic incantation to make that happen.


(Note that I'm a novice at WPF, and there may be a better way to do this...)

Comments (2)

  1. PK says:

    This is interesting.  I’m trying to do similar bitmap saves of a canvas.

    There are two problems I’m having…

    * The line ‘Canvas canvas = new canvas(…);’ can take a second or sometimes more to complete.  I find this amazingly slow (I’m doing this on a reasonably new machine.)

    * There is no documentation!  Unless I’ve completely missed it — this is something I really can’t believe — no-where is there a full description of either the XAML specification or some readable documentation about the C# functions.  This means that most of the success I’ve had has been asking people who know or flailing around in the dark!

  2. Mr Webber says:

    Hi,

    I am trying to produce a screenshot of my WPF canvas in VB.NET. However when I use the above code, as well as another similar approach I have found, it produces a totally black image. The dimensions are correct etc but nothing is actually contained in the image but black pixels.

    Does anyone have any ideas what might be causing this?

    MW

Skip to main content