Saturday, June 07, 2008

Deep Zoom API

Is there a Deep Zoom API?
No API yet but this discussion explains the use of the SparseImageTool.exe to achieve a degree of automation.

OK, felt the need to post this link from the above forum. Hven't tried it out yet but Giorgio Sardo has apparently built a c# wrapper around the SparseImageTool.exe

Deep Zoom Imagemapping

Trying to find how to make an imagemap style Deep Zoom collection in a similar way to the way the Hard Rock Memorabillia site does and came across this post by Jim Lynn. It explains how to go about making a hit detector by explaining all the head messing stuff surrounding pixel sizes, viewport origins and widths and so on. Coupled with some talking to javascript, we have a means of calling javascript functions when a particular DZ sub image is in a particular part of the viewport. Yay!

Make sure your Silverlight object has an onLoaded handler associated with it, so:
<param value="OnSilverlightLoaded" name="onload">
or set the OnLoad attribute in the asp:silverlight tag if using the .aspx route

Then add the following javascript functions:

function OnSilverlightLoaded(sender, args)
{
document.getElementById("sl1").Content.EntryPoint.CallbackToBrowser = onManagedCallback;
// where sl1 is the clientID of the Silverlight Control
// You _should_ be able to use sender but I couldn't get this to work and I had to go feed the baby!
}

// Our callback handler
function onManagedCallback(sender, args)
{
// Basically, do whatever. The _stuff_ is in args.Data
var target = document.getElementById("eventDiv");
eventDiv.innerHTML = args.Data;
}

In your Page.xaml.cs

[ScriptableMember()]
public event EventHandler CallbackToBrowser;

public class EventArgs : EventArgs
{
private T _data;
public EventArgs(T args)
{
_data = args;
}

[ScriptableMember()]
public T Data
{
get
{
return _data;
}
}
}

private void DetectCollision()
{
if (CallbackToBrowser != null)
{
int imageIndex = -1;
Point viewportCenter = new Point();
viewportCenter.X = msi.ViewportOrigin.X + (msi.Width/ 2);
viewportCenter.Y = msi.ViewportOrigin.Y + (msi.Height / 2);
if (HitTest(msi, viewportCenter, ref imageIndex))
{
CallbackToBrowser(this, new EventArgs("We hit: " + imageIndex.ToString()));
}
else
{
CallbackToBrowser(this, new EventArgs("No image"));
}
}
}

/// Given an element point relative to the DeepZoom image
/// return whether the point hits any subimages in the collection
/// parentImage: Parent image whose subimages we want
/// to test
/// p: Point to test (in element coordinate space)
/// imageindex: index into the SubImages collection
/// returns: true if a hit was found
/// http://jimlynn.blogspot.com/2008/04/silverlight-deep-zoom-collections-and.html
private bool HitTest(MultiScaleImage parentImage, Point p, ref int imageindex)
{
bool gotHit = false;
for (int i = 0; i < parentImage.SubImages.Count; i++)
{
MultiScaleSubImage image = parentImage.SubImages[i];
// Start with the logical origin of the image
Point topLeft = image.ViewportOrigin;

// Relative to the parent image, this coordinate is
// scaled by ViewportWidth (and the coords are negative)
topLeft.X = -(topLeft.X / image.ViewportWidth);
topLeft.Y = -(topLeft.Y / image.ViewportWidth);

// Calculate the logical width relative to the parent
double width = 1 / image.ViewportWidth;
// And get the height from the aspect ratio
double height = width / image.AspectRatio;

// Create a point representing the bottom left logical point
Point bottomright = new Point(topLeft.X + width, topLeft.Y + height);

// Now we've got the topleft and bottom right points
// in coordinates relative to the parent MultiScaleImage
// We can now use LogicalToElement to convert to Silverlight
// coordinates
topLeft = parentImage.LogicalToElementPoint(topLeft);
bottomright = parentImage.LogicalToElementPoint(bottomright);

// Now do the hit test
Rect r = new Rect(topLeft, bottomright);
if (r.Contains(p))
{
gotHit = true;
imageindex = i;
image.Opacity = 1;
}
else
{
image.Opacity = 0.8;
}
}
return gotHit;
}

and then call
DetectCollision();

in the appropriate handlers. If you edit the Page.xaml.cs generated by Deep Zoom Composer then it will contain a block of code containing the appropriate handlers for zooming and dragging written by Messrs Lutz Gerhard, Peter Blois, and Scott Hanselman.

I added it to the MouseLeftButtonUp handler, MouseMove handler and Zoom method

Monday, May 19, 2008

Premier Pro CS3 Multicam

Using the multicam support in PP CS3 is a pretty straightforward. WHen I first set it up I watched some chap's video tutorial (read as torturial) where he described the process with four cameras, explaining each process for each camera. Tedious.

Here's my abridged version from a developer's perspective:

create sequence 'multicam'
foreach camera source
{
import source to bin
create sequence
add video to sequence
add sequence to 'multicam'
}
create sequence 'final'
add 'multicam' to 'final'
right click 'final' sequence, select multi-camera and enable


Note that video track #1 will, by default, be used as the audio source. You can of course swap around afterwards.