Upcoming Webinar: Using a VideoBrush in Silverlight for a Media Magnifying Glass


image

I've been working on a Silverlight 1.0 sample that I'd like to share with you for two reasons:

  1. I think it's a great application of the VideoBrush feature in Silverlight which enables you to route video to any shape's stroke or fill.
  2. I need a little bit of help with the math to get the zooming right.

The sample which you can see here is a magnifying glass that zooms in on whatever portion of a playing video that it's over.  This effect is done through using the VideoBrush in Silverlight 1.0.  Typically you would hide the source MediaElement for the VideoBrush, but in this case I wanted to show both.  By doing that I keep the two videos in synch.

I plan on submitting this sample to the gallery on Silverlight.net but I need to get some of the math right when you zoom in/out the magnifier.  You will notice that the center is not correct once you rotate the zoom lever. 

What are the applications of this technique:

  1. Add a magnifier to any Silverlight application that uses video
  2. Change the brush shape from a circle to a binocular shape.
  3. Hunting game

Upcoming Webinar

On Friday February 15, 2008 at 10:00 PDT, I will be hosting a free webinar where I will explain how I built this demo. Register here.  It will be recorded if you cannot make the live event.

Source Code

I have attached the source code to this Post (without the Bear.wmv video - it comes with Windows Vista in the Sample Videos folder).

Some Math Help Please

If you like this demo, and are good at math, I need your help.  If you rotate the zoom handle you will notice that the magnified video gets offset incorrectly.  I would love any help the Silverlight community would like to offer to help me with my math to get it right. 

MagnifierDemo.zip

Comments (8)

Cancel reply

  1. I've been working on a Silverlight 1.0 sample that I'd like to share with you for two reasons

  2. Deyan Vachev says:

    Hi Michael,

    I’m one of the guys that work on the Bookvar.net project that you blogged a while ago on your blog. Your sample idea is great and I’m willing to help you on the math side. Currently I’m working on a commercial project that does some thing quite similar to this and I got it zoom correctly so I’m pretty sure I can help. Later today I’ll look at your sample and send you back some suggestions on how to solve the problem.

    Greetings,

    Deyan

  3. Michael Sherotter ( Synergist ) created a nice Silverlight 1.0 sample showing how to use the videobrush

  4. Brian Henderson says:

    Will a recording of this webinar be made available?  Are past webinars available for viewing?  (Perhaps an opportunity for a Silverlight application.. 😉  Thanks,

  5. Synergist says:

    Brian,

    As I wrote in the post, the webinar will be recorded.  All of my past webinars can be found here: http://listas.labs.live.com/user/synergist/rss/cbed11a9-a1a2-4209-b4a8-d669e4c477e5

    Michael

  6. Ben Hayat says:

    Any chance you can do your Webinar in SL 1.1(2.0) with C#?

  7. When you get backed-up, it's not pretty… this isn't everything: Denislav Savkov's BarChart

  8. rambler.elf says:

    Hi Michael,

    today, when I was in the pete blog (http://community.irritatedvowel.com/blogs/pete_browns_blog/default.aspx), I’ve seen a picture of your application, really nice, good work 😉

    as I see this application is published about 23 days, but I can’t see any comment about your calling for math help (maybe you corrected that or someone sent an e-mail to you), but let me to post myself correction :

    Synergist.Magnifier.prototype._UpdateTranslation = function()

    {

       ///<summary>Update the translation of the VideoBrush to reflect the magnification and position of the magnifying glass</summary>

       if (this.MediaElement.NaturalVideoHeight == 0)

       {

           return;

       }

       // the position of the magnifier

       var left = this.Canvas["Canvas.Left"];// + this.Canvas.Width / 2;

       var top = this.Canvas["Canvas.Top"];// + this.Canvas.Height / 2;

       var mediaLeft = this.MediaElement["Canvas.Left"];

       var mediaTop = this.MediaElement["Canvas.Top"];

       var halfWidth = this.Canvas.Width * 0.5;

       var halfScaledWidth = halfWidth * this.BrushScale.ScaleX;

       var offsetX = left – mediaLeft;

       var offsetY = top – mediaTop;

       var naturalAspect = this.MediaElement.NaturalVideoWidth / this.MediaElement.NaturalVideoHeight;

    var videoAspect = this.MediaElement.Width / this.MediaElement.Height;

    var topMargin = 0;

    var leftMargin = 0;

    if (naturalAspect > videoAspect)

    {

       var visibleHeight = this.MediaElement.Width / naturalAspect;

       topMargin = this.BrushScale.ScaleX *(this.MediaElement.Height – visibleHeight) / 2;

    }

    else

    {

       var visibleWidth = this.MediaElement.Height / naturalAspect;

       leftMargin = this.BrushScale.ScaleX * (this.MediaElement.Width – visibleWidth) / 2;

    }

       this.BrushTranslation.X = mediaLeft+leftMargin-(offsetX *this.BrushScale.ScaleX)- (this.Canvas.Width*this.BrushScale.ScaleX) / 2;

       this.BrushTranslation.Y = mediaTop+topMargin-(offsetY *this.BrushScale.ScaleX)- (this.Canvas.Height*this.BrushScale.ScaleX)/ 2;

       window.status = mediaLeft+’|’+scaleOffsetX+’|’+offsetY+’|’+this.BrushScale.ScaleX.toString();

    }

Skip to main content