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

  • Anonymous
    February 04, 2008
    I've been working on a Silverlight 1.0 sample that I'd like to share with you for two reasons

  • Anonymous
    February 04, 2008
    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

  • Anonymous
    February 05, 2008
    Michael Sherotter ( Synergist ) created a nice Silverlight 1.0 sample showing how to use the videobrush

  • Anonymous
    February 07, 2008
    Will a recording of this webinar be made available?  Are past webinars available for viewing?  (Perhaps an opportunity for a Silverlight application.. ;)  Thanks,

  • Anonymous
    February 07, 2008
    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

  • Anonymous
    February 08, 2008
    Any chance you can do your Webinar in SL 1.1(2.0) with C#?

  • Anonymous
    February 11, 2008
    When you get backed-up, it's not pretty... this isn't everything: Denislav Savkov's BarChart

  • Anonymous
    February 26, 2008
    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.Widththis.BrushScale.ScaleX) / 2;    this.BrushTranslation.Y = mediaTop+topMargin-(offsetY this.BrushScale.ScaleX)- (this.Canvas.Heightthis.BrushScale.ScaleX)/ 2;    window.status = mediaLeft+'|'+scaleOffsetX+'|'+offsetY+'|'+this.BrushScale.ScaleX.toString(); }