#.think.in
learn.create.enjoy

Creating Deep Zoom-able presentations

June 25, 2008 16:37 by brodie

Ever since I saw the Deep Zoom presentations at Remix08 Melbourne I was gob-smacked at how cool they were I wanted to give it a try.  The smooth zooming and panning was incredible to watch and was much better than the boring old Powerpoint transitions.

So how do I do this ... well, as usual the first step was to Google for the solution and the best links I found about the topic were ... here and here

 

They made it sound relatively straight forward but I struggled a little along the way.  In particular I couldn't find an easy way to generate high resolution images from powerpoint, and the high resolution images are the key for a decent looking deep zoom experience as I found out.

Anyway's, here's what I did ...

1. Use PowerPoint 2007 to create the presentation, which by the way has awesome image generation capabilities for roundpanels, arrows, smart art, etc.  Even a humble developer such as myself can create pretty good looking slides that a hardened designer would take the time to glance at.

2. Next, upgrade to latest deep zoom composer, you'll probably also need to install some silverlight goodies to get this going.

3. Generate some high resolution images from PowerPoint.  The higher the resolution the images the better experience you'll get out of DeepZoom.  Powerpoint allows you to save each slide as an image which is great, simple and easy ... but I couldn't figure out how to maximize the resolution.  There are a few settings you can tweak and apparently some registry hacks but nothing I tried seemed to work.  When you view these images in your deepzoomed presentation they appear really blurred which is no good for anyone.

So I went down the track of saving the PowerPoint presentation as a pdf using the PDF995 print driver which works great.

Now I just needed to produce  high resolution images from the PDF ... which you can, but I couldn't find a tool that would do it for free without watermarking the images.

So out of pure frustration I just used the snapshot feature of the Acrobat reader, and pasted each slide image into Paint.NET, and saved that as a PNG. A little monotonous but it gave me much better resolution images than PowerPoint.

I'm sure there is an easier way than this, so if you find one then please let me know.

4. Then just use the deep zoom composer to setup you presentation and export it. This produces a couple of projects, Silverlight and Web Application, with a html page containing the silverlight deepzoom object. Open this up and as long as you have the Silverlight plugin installed then you away laughing. Well almost.

 

Increase resolution for full screen browsing.

depending on your screen resolution you'll most likely want to increase the default resolution produced by the Deep Zoom Composer,  otherwise the deep zoom appears in a bounded window within the browser, and I wanted a full screen experience when pressing the F11 key on IE7.

So you'll need to open up the solution file in Visual Studio which may mean installing Silverlight 2 beta 2 ... argh! More on that later.  So if you manage to get that installed then ...

Modify the Page.xaml width and height of the UserControl ...

<UserControl x:Class="DeepZoomProject.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="1280" Height="1024">

... and also the MultiScaleImage tag...

<MultiScaleImage x:Name="msi" MinHeight="480" MinWidth="640" Height="1024" Width="1280"/>

I also changed the width and height of the silverlight object in the html page of the Web Application project

object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="1280" height="1024"

... then rebuild the project.

Now when viewing in the IE browser hit F11 and yet again you're away laughing.  Well, almost, really...

 

 

Hosting a Silverlight site with IIS6

Since I wanted to access the DeepZoom presentation from other machines in the network I created a virtual directory in IIS6, pointed it to the DeepZoom Web project, but when I tried to browse the html file I experienced a javascript error.

The contents read something like ...

Unhandled Error in Silverlight 2 Application

Code: 2014

Category: Initialize Error 

Could not download the Silverlight application ... blah blah blah

 

Apparently you need to do the following ...

1. Enable the content expiration setting to be one minute

2. Register some MIME typesand file extensions...

xap  application/octet-stream

.xaml application/xaml+xml

3. Change the execute permissions to "Script Only"

then presto ... all is good.

 

Solution I found was in ...

http://weblogs.asp.net/javiervillarreal/archive/2008/06/14/silverlight-error-2104-could-not-download-the-silverlight-application-in-iis6.aspx

Thank-you kind sir.

 

Fixing Silverlight beta 1 to  Silverlight beta 2 problems

... and there are plenty of them

In getting this to work I experienced some mild unpleasantness, almost approaching the absolute disgust I faced when trying out the alpha releases of silverlight which required a complete reinstall of my OS! .. there's a couple of days I'll never get back!

Anyway's, try here for starters ...

http://weblogs.asp.net/bradleyb/archive/2008/06/18/fixing-setup-errors-installing-silverlight-tools-beta-2.aspx

and read my contribution ... http://silverlight.net/forums/p/18765/64872.aspx#64872, yep, not much.

 

Personally though, my installation is still a little stuffed, as I can't debug silverlight applications ...

so I'll probably end up reinstalling all VS and silverlight stuff :-( unless I find a solution in the next couple of days.

 

Technorati Tags: ,

Page summary in Google search results

June 23, 2008 15:46 by tarn

I just realised the summary of some of my pages in Google search results were terrible. So I looked into sites that had good descriptions and discovered Google will use the "description" meta tag for the summary when it's present.

<meta name="description" content="Your Page Summary Here!">

This is easy to do for static pages, and is not the hard to do for dynamic pages. If you use Master Pages its common to define a place holder inside the head tag. This means any dynamic pages can implement a content server control for that place holder and insert a meta tag with relevant information to be displayed in the summary of the Google search results.

You could also give the head tag ID and runat="server" attributes. This means you can find it when your processing the page and dynamically append a meta tag element to its children property.  

 

Tags:
Categories:
Comments (0)

Minify Javascript

June 22, 2008 22:04 by tarn

One of my favourite books on web development is High Performance Web Sites: Essential Knowledge for Front-End Engineers by Steve Souders. From the authors role as Chief Performance Yahoo! he describes 14 surprisingly simple rules for improving front end performance of web sites. Most professional web developers should know most of the best practices, but might also pick up a tip or two. The rules are justified with quantifiable test results, which is great when you're trying to convince a manager its worth while implementing front end improvements.

There also is 34 categorized rules for best practice on the Yahoo! web site. Yahoo! provides YSlow a plug-in for Firefox which analyses pages and explains rules that would improve front end performance. 

This post is about implementing rule 10, Minify JavaScript. I have known about minifying Javascript for a long time but had never implemented it, today I decided to give it a go on a site I run. I had a look at a few minifying tools:

JSMin - Created by Douglas Crockford, JSMin is the most basic of the minifying tools I've seen out there. It has been ported to .Net, but its not really a very sophisticated tool. It removes line breaks, white space and doesn't do any variable renaming. There is a site that you can paste some JavaScript in a compress it with JSMin or Packer to have a look at the output.

Packer - Created by Dean Edwards, Packer uses a different approach to minifying JavaScript. Packer compresses the code into an expression that can be evaluated to its original form by the Javascript eval function. I think this is cool and I'm not influenced by people out there saying you should never use the eval function. Packer is used and the eval function has been around since Javascript 1.0, it will be supported by modern browsers I'm supporting. The two main criticisms of Packer I am a little concerned about are;  There is a delay after the script is received by the browser before it evaluates to your actual Javascript code. With that in mind, unless you design the page well, you may intermittently cause Javascript errors by referencing code that doesn't yet exist. The second criticism that while packers compression is very good, it doesn't compress much more when gziped before being sent to the browser. Packer has been ported to .Net, Perl and PHP.

YUI Compressor - Created by Yahoo!, this is what I wanted in a minifying tool. It removes all unnecessary characters and does variable renaming. The YUI Compressor is implemented in Java, there is an open source project on CodePlex to port it to .Net but at the time or writing this, it has only ported the CSS compression algorithm. Julien Lecomte an architect at Yahoo talks about the YUI Compressors performance in his blog.

Dojo ShrinkSafe - Create by the Dojo people, it seems to be doing the same thing as the YUI Compressor. I didn't look very hard, but I didn't find a .Net port for this one either.

There is also Minify a PHP library on Google Code for creating servers that can combine and minify script files on the fly before they are sent to the browser. The project I'm working on is hosted by IIS and S3 so I didn't look into this any further.

I decided to try the Yahoo YUI Compressor and Dojo ShrinkSafe even though there was no .Net port for either. JSMin didn't provide the compression I wanted to make it worth while. I outlined some of my concerns about Packer, and I decided I would just prefer plain compacted Javascript.

Then the was the question of whether its ok to use a Java application in my .Net build process? Java is a free and widely used platform, and in this case the best tools for are built on it. I have the JRE on all the computers I use anyway, so for me its no problem. If you need to compress scripts at runtime in .Net it may be worth looking a bit further into other .Net solutions and ports. 

Both the Yahoo! and Dojo compressors were easy to use from the command line:

java -jar yuicompressor-2.3.5.jar scripts\combined.js -o scripts\yui_compressed.js 
java -jar custom_rhino.jar -c scripts\combined.js > scripts\dojo_compress.js 2>&1

The only thing I had to do to get them working was change the UFT-8 encoding of some of my script files to ANSI. After that everything on my site worked as is should with both libraries. If I had any problems I was going to give JS Lint a try. It is recommended to use JS Lint to verify your Javascript before compressing it.

After using a tool to combine my uncompressed script files, the final script was 16,042 bytes. Below are the result of using ShrinkSafe and YUI Compressor on that code:

Tool

Final Size

Compression %

Dojo ShrinkSafe

11,543 bytes

71%

YUI Compressor

10,448 bytes

65%

 

So what did I discover? I was really happy with both tools, they both compressed and didn't break my code. Because both can be run from the command line they should be easy to integrate into my build process, provided my build and development machines have Java installed.

At this stage I'm not gziping my scripts, but that has more to do with my applications architecture, the scripts are being served by a storage in the cloud solution. I may look into providing the correct meta data to statically host gziped scripts, but that will be the topic for another post.

As for getting it into my build process I just used the post build tasks hook in Visual Studios. It could just as easily be part of your NAnt script.

I hope this helps the front end performance of your web pages too.


Tags:
Categories:
Comments (0)

Anonymous Methods - Understanding Scope

June 19, 2008 11:42 by tarn

Anonymous Methods were introduced in .net 2.0. If you haven't used or seen them before I suggest reading some of the many blogs and MSDN articles about them. I'm not going to introduce them here, I'm going to briefly look into how the scope works when they are invoked from outside the scope they were created in.

Below I have a simple example of a class that has a member variable and a method that returns an anonymous method. The only purpose of this little class is to investigate some scope issues.

public delegate string FooDelegate();

public class Foo
{
    public string Bar { get; set; }
    
    public FooDelegate GetDelegate()
    {
        string bar = Bar;
        return delegate()
            {
                return string.Format("Member: {0}; Local: {1}", Bar, bar);
            };
    }
}

You can see that in this class the anonymous method we are creating references a local variable and a member variable of the class. This is completely legitimate code in .net 2.0, 3.0 and 3.5. Now lets see how it works, below is a simple example.

Foo foo = new Foo();
foo.Bar = "test";
FooDelegate fooDelegate = foo.GetDelegate();
string result = fooDelegate.Invoke();

 

The result is "Member: test; Local: test"

You can see that when we invoked the anonymous method both the local and member variables evaluated  to "test". Once you accept its ok to reference variables from the scope the anonymous method was created in, this behavior makes sense. 

But what happens if we change the property after we create the anonymous method? What would we expect the values to be when we invoke the method? If you've used anonymous methods in other languages it might be quite obvious. If you don't know, or want to validate that you do, the example below will do just that.

Foo foo = new Foo();
foo.Bar = "test";
FooDelegate fooDelegate = foo.GetDelegate();
foo.Bar = "update";
string result = fooDelegate.Invoke(); 

 

The result is "Member: update; Local: test"

As you can the see the method did use the updated property, but only for the class property. The value of the local variable it was referring to when the anonymous method was created has not been changed.

Normally a local variable would be discarded and later collected by the GC once execution of the block is complete. In this case it's still in the scope of the anonymous method and is therefore not discarded while the anonymous method is still referenced.

The local variable is not updated with the new value as we set the local variable when we created the delegate, and we changed the class property after that. In this case we can't change the value of that variable as we no longer have a reference to it once we leave the GetDelegate() method. Its only reference by the delegate itself.

This example works because strings create a new instance of a string when they are assigned. The example would behave differently if the local variable was a reference to the same object as the class property.

Using the local variable in an anonymous method that is called from outside scope it was created might not be something you ever do in .Net, but its a concept .Net developers should understand. I've haven't been able to think of a simple, relevant, real world .net example for this, but I do use the same concept in some Javascript I write about in another post.

EDIT: This is known as closure. This article I found on the VS2008 Start Page talks about it and discusses the MSIL generated :  Lambdas - Know Your Closures


Tags:
Categories: .NET
Comments (0)

HacMan - WPF Demo Application

June 17, 2008 12:31 by tarn

HacMan is a game Brodie and I wrote to have a bit of fun trying out WPF. The game is in classic PacMan style, but our colleague S Haxby is the HacMan. His task is to fix bugs and avoid being eaten by the managers. Its far from polished code, or a complete game but I thought I'd post it anyway as its a pretty cool WPF demo. 

We tried to write the game engine decoupled from the presentation so we could also implement the presentation in DirectX or Silverlight if we wanted.

There is probably a reference to an NUnit assembly which I haven't included in project. You may need to download the latest NUnit assemblies and update the reference. Other than that its a fairly standard VS2008 project.

image

image

Source Code

Executable

Hac on..


Tags: ,
Categories: Demos
Comments (1)

If I could only read 10 blog feeds...

June 16, 2008 09:55 by brodie

In today's world of information overflow how as a developer do you keep up with all that's going on in this rapidly developing community? Well, it's difficult, but you can conquer it just by being a little bit more organized.

First of all if you aren't using an RSS Feed Reader these days then forget about it - it is the most efficient way to scan and read multiple websites.  Now there are plenty of readers available these days, google has one, outlook has one, but I'm still using SharpReader as my feed reader, it's been around a while but I've always liked its features and it's simplicity. 

I've probably got around one hundred feeds that I subscribe to which is way too many, so I thought I'd do some culling and try to bring it down to ten feeds that I couldn't do without.

So here are my top ten feeds...

 

  1. Reflective Perspective (The Morning Brew) I always start my day with this great link blog which has kept me well informed on all things developer related (with perhaps more of a Microsoft slant).  Ever since Mike Gunderloy moved to the Ruby world and stopped writing The Daily Grind I was slightly devastated, but Chris Alcock's morning brew has filled the void.  My backup linkblog which is also top notch is Arjan's World , and if they both go down then I'll also have A Continuous Learner's Weblog just in case.  If you were just to read these three feeds then you'd be a very well informed developer (well, .Net developer anyways).
  2. I've been following Scott Hanselman's Computer Zen for quite some time and it is by far the best coder blog out there with great insights, code examples, technology reviews, and generally just well written articles.  When Scott H got assimilated into Microsoft I noticed more and more references to his alter ego Scott Guthrie (who's actually his boss).  I would include Scott Gu's blog in my top ten except Scott H always covers anything "the Gu" writes.
  3. Coding Horror  by Jeff Attwood ... always finds something controversial to write about and has no trouble expressing his opinions. Very well written articles and great content, more focused on developer psyche and  philosophy than hard core coding examples. 
  4. 37 Signals  - The main guy here, David Hansson, founded Ruby on Rails and has some great insight into web usability and design.
  5. XKCD - To be honest, when I first found this site I spent some considerable amount of time reading through all the comics and really laughed my arse off.  I admit now that I am addicted to these comics and I eagerly await each one which generally get published like clockwork three times a week.
  6. StackOverflow is my newest favorite weekly podcast staring Joel Spolsky and Jeff Attwood. Another top podcast is   HanselMinutes , which I do listen to every week but I include it in my top ten under Computer Zen ;-)
  7. InfoQ  has great articles, pdf booklets, video interviews, on all things agile, architecture, .Net, Java, and more. A very good site which was a step up from the comparable site The Server Side .
  8. Code Better  blog is produced by a group of bloggers , some more controversial than others, ... a while back a group of the bloggers splintered off from CodeBetter and formed The Runtime - which seems to be struggling in comparison.
  9. High Scalability  - fantastic reading about architecture of some of the big websites out there, the tools they use, and lessons learnt from scaling. A must read for any serious web developer/architect.
  10. Slashdot - the original geek blog, it may not still be the best but it has to be in my top ten for nostalgic reasons.

 

I guarantee you that if you read and keep up with all these blogs/podcasts then you will evolve into a gun kick-ass guru developer with an attitude ;-)

 

Some other highly recommended feeds that didn't make it to my top ten...


Tags:
Categories: Developer
Comments (4)