Clicky

12 March 2008

Silverlight 2 の新機能 - Deep Zoom

MIX 08 の基調講演において Silverlight 2 の新機能として注目を集めたものに Deep Zoom という技術があります。ちょうど、Virutal Earth 技術を使っている Live Search Maps がマウスホイールを使って地図の拡大・縮小を行えるように、巨大なビットマップの全体から特定の部分までをスムーズに拡大(ズームイン)・縮小(ズームアウト)できるものです。Live Search Maps では AJAX を使っているので、少し動きがぎこちない面はありますが、Deep Zoom は、とてもスムーズにズームできます。

百聞は一見にしかず、まずは基調講演でも取り上げられた Hard Rock Memorabilia をご覧ください(もちろん、Silverlight 2 Beta 1 をインストールしておく必要があります)。マウスホイールによってイメージをズームしたり、マウスドラッグでイメージ全体を移動できますが、ズーム倍率をあげると、どんどん細かいイメージが表示されてくることがわかります。

さて、Deep Zoom 技術を使うにはどうすればよいでしょうか。これは、単純にビットマップ全体をダウンロードして表示しているのではありません(そんなことをしたら、最初に巨大なイメージデータをダウンロードすることになってしまいます)。そこで、Deep Zoom で使うためのデータをサーバー側に用意しなければならないのです。このデータを作るのが Deep Zoom Composer というツールです。まずは、このツールをインストールしてください。

※Deep Zoom Composer User Guide(PDF) が、Expression Blend and Design ブログで紹介されていますが、簡単な使い方は以下のとおりです。

  1. 新しいプロジェクトを作成する
  2. (上部のタブが "Import" になっているのを確認して)[Add Image...] ボタンで使いたいイメージを追加する(Importing と表示されてイメージが取り込まれます)
  3. 上部のタブで "Compose" を選び、右側に取り込まれているイメージを左側の領域に配置していきます。
  4. 上部のタブで "Export" を選び、右側で適当な名前(Name)を設定したのち、[Export] ボタンで出力する。
    ※エクスポート処理には、多少時間がかかります。

これで指定したフォルダにデータが作成されます。

Visual Studio 2008(Silverlight Tools をインストールした状態)で、新しい Silverlight 2 プロジェクトを作成し、さきほど生成したデータ(info.binの入っているフォルダ以下のすべて)を、このプロジェクトの Web サイトの ClientBin フォルダにコピーします(※追記。プロジェクトをビルドして .xap ファイルが作成されるまでは、このフォルダがないので注意してください)。Silverlight の XAML でこのイメージデータを表示するためには次のようにするだけです。

<MultiScaleImage x:Name="msi" ViewportWidth="1.0" Source="teched2007/info.bin" />

ただし、これだけではマウスによるズームイン、ズームアウトは実装されません。そこで、次のようにマウスイベントを処理するように定義します。なお、UserControl のサイズ(HeightとWidth)は大きな値に変更するか、削除しておくとよいでしょう)。

<MultiScaleImage x:Name="msi" ViewportWidth="1.0" Source="teched2007/info.bin"
            MouseLeftButtonDown="OnMouseLeftButtonDown"
            MouseLeftButtonUp="OnMouseLeftButtonUp"
            MouseMove="OnMouseMove"
            MouseLeave="OnMouseLeave" />

イベントハンドラは、以下のように定義します。

   public partial class Page : UserControl
    {
        private bool dragging = false;
        private bool dragged = false;
        Point dragStart;
        Point currentOrigin;

        public Page()
        {
            InitializeComponent();
        }

        private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            dragging = true;
            dragged = false;
            dragStart = e.GetPosition(msi);
            currentOrigin = msi.LogicalToElementPoint(msi.ViewportOrigin);
        }

        private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (dragged == false)
            {
                // [Ctrl] を押しているときはズームアウト(縮小)、押していないときはズームイン(拡大)
                if (Keyboard.Modifiers == ModifierKeys.Control)
                    Zoom(e.GetPosition(msi), 0.8);  // 縮小倍率
                else
                    Zoom(e.GetPosition(msi), 1.2);  // 拡大倍率
            }

            dragging = false;
            dragged = false;
        }

        private void Zoom(Point P, double ZoomFactor)
        {
            P = msi.ElementToLogicalPoint(P);
            this.msi.ZoomAboutLogicalPoint(ZoomFactor, P.X, P.Y);
        }

        private void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (dragging == true)
            {
                // ドラッグしたら、イメージを移動
                dragged = true;
                Point p = new Point();

                p.X = currentOrigin.X - (e.GetPosition(msi).X - dragStart.X);
                p.Y = currentOrigin.Y - (e.GetPosition(msi).Y - dragStart.Y);

                msi.ViewportOrigin = msi.ElementToLogicalPoint(p);
            }
        }

        private void OnMouseLeave(object sender, MouseEventArgs e)
        {
            dragging = false;
            dragged = false;
        }
    }

これで、マウスの左ボタンをクリックしてズームインしたり、[Ctrl] を押しながらクリックすることでズームアウトできるようになります。(ホイール処理については、改めて)

実際の例については、Tech Ed 2007 で撮影した写真を素材に作成してみた例をご覧ください。
http://ohno.members.winisp.net/deepzoomtest/DeepZoomTestTestPage.html
※ズームインしてもピンボケしている部分はありますが、単に撮影者の腕です^_^;

Filed under: ,
 

Comments

# develop .net said:

前エントリ では、Deep Zoom の基本的な使い方について、ご紹介しました。ここで取り上げた Hard Rock Memorabilia では、マウスのホイールによってズーム(拡大縮小)を操作できるようになっています。このホイールの機能を自分のアプリケーションに実装するにはどうすればよいでしょう。

12 March 08 at 5:59 AM
# ディベロッパー製品開発統括部 Blog said:

既にご存知かもしれませんが、 2008 年 3 月 6 日 ( 日本時間 ) 、米国ラスベガスで開催された Web テクノロジーカンファレンス MIX08 において、 Silverlight 2 の発表が行われました。

24 March 08 at 10:42 PM
# DS7のちょっとずつ said:

DotNetNuke Off Site Meeting@大阪に参加しました。

28 March 08 at 1:41 PM
# DS7のちょっとずつ said:

DotNetNuke Off Site Meeting@大阪に参加しました。

28 March 08 at 2:04 PM
Anonymous comments are disabled
Page view tracker