Charles Petzold on writing books, reading books, and exercising the internal UTM

Recent Entries
< PreviousBrowse the ArchivesNext >
Subscribe to the RSS Feed

A Fluttering Photo Effect for Silverlight 3

August 11, 2009
Roscoe, N.Y.

As I demonstrated in a previous blog entry, the new Matrix3DProjection class in Silverlight 3 lets you define 2D non-affine transforms to shift the sides of any Silverlight element into an arbitrary convex quadrilateral. But what if you want to get more extreme? What if you want to make a bitmap look like a fluttering flag, for example?

That's possible as well, as the following demo program shows:


You might want to upgrade your machine to run this one!

Here's the source code. I created the project under Visual Studio 2010, but it would be easy enough to copy the Page.xaml and Page.xaml.cs files into a new Visual Studio 2008 project.

The first step to manipulating an image (or some other element) in this way is to cut it up into pieces — a bunch of tiny square bitmaps all the same size — and assemble them in a grid. The WriteableBitmap class (also new in Silverlight 3) is ideal for this purpose. (Actually, I think it's pretty much essential because I don't see another way to do it in Silverlight code.) The code is in the PrepareImage method in Page.xaml.cs. From what I can gather, the FrameworkElement derivative you pass to the Render method of WriteableBitmap must be a visible element in layout, but that element — or a part of it with an optional transform — is plastered onto the surface of the bitmap. Notice that each of these tiny bitmaps encompasses 20 square pixels of the original image, but I made the bitmaps 21 pixels square so they slightly overlap and avoid thin white lines between them that appeared otherwise.

Now that the image has been reproduced with a grid of tiny bitmaps, each of these bitmaps can be subjected to a different 2D non-affine transform. If you make sure the corners always meet and that the transforms don't result in non-convex quadrilaterals, if will seem as if the whole image is being warped in some way.

That's the purpose of the TransformImage method in Page.xaml.cs. For this particular effect I used two animated sine curves, one for the top and one for the bottom, and just interpolated between the two to move the coordinates of the grid around. From these shifted coordinates, the CalculateNewTransform method (very similar to the one in that earlier blog entry) calculates a Matrix3D for each little bitmap in the grid.

I'll post another example of this technique in a day or two.


Ahhh... this is reminiscent of Windows' 3D Flying Object screensaver!

David McClelland, Tue, 11 Aug 2009 17:00:10 -0400 (EDT)

You could probably do this with a pixel shader as well, nice sample.

— Bill Reiss, Wed, 12 Aug 2009 15:47:51 -0400 (EDT)

I haven't been able to get into pixel shaders yet, but it'd be interesting to see the performance difference. — Charles

hello sir...

we know now that Windows 7 will be the native coders paradise and im wondering if u r going to update your legendary win32 api book "programming windows". i imagine an updated content of the basic win32 api stuff with the GDI parts replaced by the new direct2d api. come on man ... u can do it again and u can update that legendary windows programming bible. i know that might not happen but i can keep dreaming it will :D.

thank u so much for the knowledge u spread all over the world.

— Wed, 12 Aug 2009 20:53:50 -0400 (EDT)

It is not I who decides whether to update the book. Microsoft Press must make that decision, and so far they have not mentioned it to me. (And I'm not sure if I'd be able to accept the offer. Judging by the terrible sales of my last two books, spending six months updating "Programming Windows" for Windows 7 is likely to lead directly to homelessness.) — Charles

Yes the perf is pretty poor could when compared to the jellophysics samples eg: Could you use multiple clip paths on the one imagebrush like the video jigsaw

Then do the math on the planetransform on your path/polygons to skew the individual clipped images?

— slyi, Fri, 14 Aug 2009 04:38:55 -0400 (EDT)

I'm with Bill: I'm almost certain perf will improve if you use a pixel shader, even though pixel shader effects aren't eligible for GPU execution. One by product of using a pixel shader is that you could expose a dependency property or two and animate the shader to produce a waving flag!

— Jeff Prosise, Mon, 26 Oct 2009 14:09:27 -0400

Recent Entries
< PreviousBrowse the ArchivesNext >
Subscribe to the RSS Feed

(c) Copyright Charles Petzold