Wednesday, March 7, 2012

Using SeaDragon Ajax to Display DeepZoom Content in Windows8 Apps

Download sample project

MultiScaleImage was introduced in Silverlight 2 and offered great power to manipulate high resolution images on the web. Unfortunately MultiScaleImage control is not yet available to Windows 8 developers as of Consumer Preview. DeepZoom or SeaDragon research project cuts images into smaller pyramid of lower resolution tiles, and smartly brings down only the tile suitable for the current display. So a viewer can be built in virtually any technology. Microsoft provides a JavaScript viewer for DeepZoom content. The JavaScript implementation has limited features and does not support image collections and sparse images, but works very well with single images.

Using SeaDragon Ajax in Windows 8 HTML5 apps is straightforward except for few hacks to work around the security restrictions and environment difference from the browser environment.

First you need to get the source from http://gallery.expression.microsoft.com/SeadragonAjax and note that you can not reference the hosted script because access to external scripts is prohibited while in local context http://msdn.microsoft.com/en-us/library/windows/apps/hh465373.aspx.

I used the dev version of the library to face the first glitch. The seadragon-dev.js uses document.write to emit the script files required by the library. WinRT apps running in local context requires dynamic content to be secure using the window.toStaticHTML or else you will receive “JavaScript runtime error: Unable to add dynamic content. A script attempted to inject dynamic content, or elements previously modified dynamically, that might be unsafe.”.

But using the window.toStaticHTML will remove all script tags in dynamic content, which renders the code useless. Since we trust the source of the content we can use MSApp.execUnsafeLocalFunction to wrap the dynamic content creation and temporarily disable the security restrictions as shown in the following snippet.

   1:  MSApp.execUnsafeLocalFunction(function () {
   2:      document.write(html.join(''));
   3:  });




The next glitch was the unavailability of the alert function for WinJS apps, and the library use it to display errors. As a workaround I defined a global alert function that displays a MessageDialog and logs the message to JavaScript console as shown in the following snippet.


   1:  <script type="text/javascript">
   2:      var alert = function(message) {
   3:          console.log(message);
   4:          var dialog = new Windows.UI.Popups.MessageDialog(message);
   5:          dialog.showAsync();
   6:      }
   7:  </script>



The next glitch was an error “JavaScript runtime error: Automation server can't create object”. This error is caused by the library checking for window.ActiveXObject and if defined it tries to use it to create XMLHTTP object. The workaround I used is setting window.ActiveXObject to null prior to creating the viewer. After that the viewer worked flawlessly. Just make sure to include the img directory available with the source to show the icons correctly.

No comments: