Upcoming Webinar: Using a VideoBrush in Silverlight for a Media Magnifying Glass
I've been working on a Silverlight 1.0 sample that I'd like to share with you for two reasons:
- 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.
- 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:
- Add a magnifier to any Silverlight application that uses video
- Change the brush shape from a circle to a binocular shape.
- 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.
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 reasonsAnonymous
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, DeyanAnonymous
February 05, 2008
Michael Sherotter ( Synergist ) created a nice Silverlight 1.0 sample showing how to use the videobrushAnonymous
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 MichaelAnonymous
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 BarChartAnonymous
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(); }