Skip to main content
評分: 

邊做邊學 Silverlight 2 - Deep Zoom 入門


作者:賴榮樞 ( http://www.goodman-lai.idv.tw)


Deep Zoom 是一項很棒的圖形呈現技術,並且已經與 Silverlight 巧妙結合(雖然不只 Silverlight 能夠應用這項技術)。本文將從 Deep Zoom 經典應用實例的介紹作為起點,再簡述 Deep Zoom 的原理,最後輔以免費且不可或缺的工具 Deep Zoom Composer,動手完成 Deep Zoom 範例。

Deep Zoom(或 DeepZoom)是 Silverlight 內建的一項影像相關的技術,能在保持良好效能的情況下縮放大型圖檔。這項因為併購 Seadragon Software 公司而取得的技術,是 Silverlight 應用程式處理大型圖檔的利器。


【Deep Zoom 應用實例】

在討論 Deep Zoom 技術之前,本文將先介紹一些 Deep Zoom 的應用實例,希望藉此讓您瞭解 Deep Zoom 的能力,也希望能激發您應用 Deep Zoom 的創意火花。

硬石餐廳收藏品陳列網站

硬石餐廳收藏了許多搖滾巨星用過的樂器、穿過的衣物、甚或手稿,而其線上記事網站( http://memorabilia.hardrock.com/)陳列了諸多收藏品的照片。這個網站利用 Silverlight 及 Deep Zoo 技術來呈現總共 610 張的高畫質收藏品照片,為了方便瀏覽,網站所用的 Silverlight 程式可以讓使用者在網站左邊欄依據以下分類方式來找到藝人收藏品照片:

  • Show all items:列出所有照片的縮圖。
  • Featured Artists:列出特定藝人的收藏品照片縮圖。
  • Type:列出特定類型的藝人收藏品照片縮圖,例如衣物、手稿、樂器等。
  • Decade:從 1940 至今,列出各個年代的藝人收藏品照片縮圖。
  • Genre:列出特定音樂類型的藝人收藏品照片縮圖。
  • Location:列出全球各地硬石餐廳的藝人收藏品照片縮圖。

以上是以 Silverlight 製作出的功能。不論選取了哪一種分類方式,網站都會將該分類所有的收藏品照片,以小縮圖排列在網站右側的顯示區域,由於顯示區域的大小固定,因此如果該分類的照片越多,每張照片的縮圖就越小。

這個網站不只能顯示一組收藏品照片的縮圖,使用者還能:

  • 以滑鼠左鈕點選某張縮圖一次,就會放大(也就是 zoom in)該張縮圖一次。
  • 先按 Shift 按鍵不放再以滑鼠左鈕點選某張縮圖一次,就會縮小(也就是 zoom out)該張縮圖一次。
  • 以滑鼠拖曳來移動照片。
  • 若滑鼠指標位在顯示區域裡,也能以滑鼠滾輪來放大或縮小照片:向上滾動是放大,向下滾動是縮小。

以上這些功能就是利用 Deep Zoom 所完成。也由於這些照片的解析度都很高,這個網站也利用漸進方式顯示照片,也就是在放大照片時,讓照片內容一層一層逐漸清楚,而這也是 Deep Zoom 內建的功能。

DeepEarth

檢而言之,DeepEarth( http://www.codeplex.com/deepearth/)結合了微軟的 .NET、Silverlight、Deep Zoom 技術和 Virtual Earth 服務,除了實作成控制項,也以 Microsoft Public License 的授權方式釋出原始碼。

開發者除了能將 DeepEarth 控制項用在自己的 Silverlight 應用程式,也能取得原始程式碼。在 http://deepearth.soulsolutions.com 則有 DeepEarth 的實作示範。

回到首頁


【特性簡介】

Deep Zoom 原本屬於 Seadragon Software 這家 10 人公司的技術,公司創辦人是 Blaise Agüera y Arcas。2006 年一月,微軟併購了 Seadragon Software 公司,並且也取得這家公司的技術(及工程人才)。隨後微軟將這些技術納入 Microsoft Live Labs 繼續發展,而且也開啟了 Seadragon 專案。

Seadragon 專案最大的目的是希望不論資料量或網路頻寬的多寡,都能更平順的瀏覽圖形和照片,甚至改變我們使用螢幕的方式。這個專案有許多成果,包括 Seadragon Mobile、Seadragon Ajax,以及本文的重點--Deep Zoom、Deep Zoom Composer。

Deep Zoom 是一項能以更有效率的方法讓用戶端使用者瀏覽高解析度大圖的技術;我們甚至可以這麼說:Deep Zoom 是為了提供更好的Web圖形瀏覽體驗而生,尤其是對大圖檔或網路頻寬較低的情況而言,Web 圖形瀏覽體驗更為重要。這項技術目前已經整合到 Silverlight 2.0,而 Deep Zoom Composer 則是應用 Deep Zoom 技術時,不可或缺的圖形處理輔助工具。

Deep Zoom 具有以下的特性:

  1. 漸進呈現圖檔內容:Deep Zoom 最基本的特性是能漸進呈現圖檔內容,也就是先呈現整張圖模糊的大概,然後再逐漸逐漸的讓圖清晰。Progressive JPEG 格式也有類似的作法。
  2. 先看縮圖再看大圖:同樣也是漸進呈現的概念,Deep Zoom 可以在顯示圖形時,先讓使用者看原圖縮成的小圖,再由使用者決定要不要放大觀看,而且可以讓使用者分成多次放大到原圖--也就是有數種不同大小的縮圖。
  3. 將大圖分割成小圖:除了縮圖,Deep Zoom 還能分割原圖及縮圖(以 256 像素為單位),以便分塊顯示圖檔的某個部分;只載入某個部分所需要的時間,會小於載入整張圖。
  4. 可程式化的影像集合:Deep Zoom 可以從各個圖檔建立影像集合,並提供可程式化的方式來操控或找出集合裡的圖檔。

只要瀏覽過本文前述提及的 Deep Zoom 應用實例,應該就能發現以上所提的 4 點特性。例如硬石餐廳的收藏品陳列網站,每一種分類所呈現的收藏品縮圖而成的圖片,就是一個影像集合。

先看縮圖再看大圖

以往我們在處理網頁裡的圖形時,經常堅守的原則是將圖檔品質降到適用於螢幕即可,這能降低圖檔對頻寬及下載時間的需求。但對於某些希望呈現高品質圖形的應用,我們就得針對每一張圖,分別製作高品質和低品質兩種不同的圖檔,適用於螢幕解析度的低檔圖供作預覽,如果使用者想看細節,就再點選高檔圖。前述的「先看縮圖再看大圖」也是源自相同的概念,而且透過工具能產生不同尺寸的縮圖,供使用者逐步放大觀看。這種不同品質的整組圖檔稱為「金字塔」(pyramid)影像。Deep Zoom 影像金字塔僅支援 BitmapImage 類別所支援的圖檔,包括 Tiff、Bitmap、JPEG 和 PNG。

在執行的時候,Silverlight 應用程式會先載入低檔圖的某一塊,然後再根據使用者的操作(例如移動或放大圖形),及時載入其他圖形。也就是說,Deep Zoom 利用由低檔到高檔的漸進方式來顯示圖形,以達到更好的 Web 圖形瀏覽體驗。

回到首頁


【動手實作】

大致瞭解 Deep Zoom 技術的應用、來由、特性之後,接下來該是捲起袖子動手實作範例的時候。這個簡單的 Deep Zoom 範例會用到 Deep Zoom Composer、Visual Studio 2008 等工具,目前 Deep Zoom Composer 仍處於持續發展的狀態,本文所用的版本是 0.9.000.6,如果想下載最新版本,請到 Microsoft Download Center 搜尋。

  1. 執行 Deep Zoom Composer 之後,請以「File/New Project 」命令建立新的 Deep Zoom 專案,本例的專案名稱是 dzTai,也請依照您的情況指定適當的位置。



    圖 1 Deep Zoom Composer 的 New Project 交談窗
  2. Deep Zoom Composer 有 3 個工作區:Import(匯入)Compose(編排)Export(匯出)。建立 Deep Zoom 專案之後要先匯入圖檔,如果工作區不在 Import,請先按「Import 」



    圖 2 先按「Import 」,再按「Add image 」
  3. 然後再按下 Deep Zoom Composer 視窗右上方的「Add image 」來匯入專案所需要的圖檔,這會出現「Add Image 」交談窗,而且允許一次匯入同一資料夾的數個圖檔(請注意,Deep Zoom Composer 不允許匯入名稱相同的檔案)。



    圖 3 Deep Zoom Composer 可以一次匯入同一資料夾的數個圖檔
  4. 匯入之後,Import 工作區可以檢視匯入的圖檔。



    圖 4 Import 工作區可以檢視匯入的圖檔
  5. 我們先暫停操作,看看 Deep Zoom Composer 到目前為止產生了哪些資料夾和檔案。請以「檔案總管」開啟步驟 1 所指定的位置,然後會看到以下資料夾及檔案:
    • dzTai.dzprj:Deep Zoom 專案檔。
    • Exported Data(稍後會討論這個資料夾)。
    • Source Images:Deep Zoom Composer 會在這個資料夾存一份匯入圖檔的備份。
    • Working Data:Deep Zoom Composer 匯入圖檔時,就會對原圖進行縮圖分割,而各種尺寸的縮圖和分割後的圖檔,就放在 Working Data 資料夾。在這個資料夾裡,每個匯入的圖檔會各擁有一個與圖檔名相同的資料夾和 XML 檔,XML 檔記錄圖檔的格式、長寬、分割大小(256)等資訊,而每個資料夾裡還會有一群資料夾(這群資料夾裡的圖檔構成了前述的「金字塔影像」,裡面的每一個資料夾存放了一種縮圖尺寸的圖檔,如果縮圖大小的像素超過 256,就會分割成數個小圖。以圖 4 工作區所呈現的圖檔 dcs07792 為例,在其 dsc07792_files 資料夾底下有名稱為 0 到 11 等 12 個資料夾,在資料夾 0 到 8 裡的縮圖都很小(尤其資料夾 0 到 3 裡的縮圖更小),因此這些資料夾裡都只有 1 個圖檔。從資料夾 9 開始的縮圖就大到必須分割成 6 個小圖,而資料夾 11 裡的圖更是分割成 63 個。
  6. 接著我們要編排匯入的圖檔,請按「Compoese 」進入「Compose 工作區 」,然後從工作區右側的 Images gallery 將圖檔拖入工作區;我會將這 4 個圖以如下方式排列。



    圖 5 編排匯入的圖檔
  7. 然後是匯出的步驟,請先按「Export 」,再按「Custom 」,並且依照以下調整設定,最後再按「Export 」:
    • Output type(匯出類型):「Silverlight Deep Zoom 」
    • Name(名稱):tai(此亦為存放匯出結果的資料夾名稱)
    • Location(位置):保持預設值
    • Image settings:Export as a composition (single image)(匯成單一圖檔)
    • Format:JPEG
    • Quality:100


    圖 6 匯出的設定
  8. 完成匯出之後,Deep Zoom Composer 除了會以交談窗告知匯出成功,交談窗還可將結果開啟到瀏覽器預覽(Preview in Browser)、檢視圖檔資料夾(View Image Folder)、檢視 Silverlight 專案資料夾(View Project Folder)、連到相關網頁。



    圖 7 「Export Completed 」交談窗
  9. 我們先按下上述交談窗最左邊的按鈕來預覽匯出結果,而且只要以滑鼠左鈕按下圖形,就會放大(zoom in)、Shift 加滑鼠左鈕可以縮小圖形(zoom out),甚至還能以滑鼠滾輪控制圖形的放大和縮小;滑鼠指標進入圖形之後,圖形的右下角還會出現4個控制鈕。這些基本的瀏覽控制功能,是 Deep Zoom Composer 自動幫專案加入。



    圖 8 預覽 Deep Zoom 專案的匯出結果

回到首頁


【Deep Zoom Composer 還產生了哪些檔案?】

Exported Data 是上述步驟 5 尚未討論的資料夾,因為當時還是空的,但 Deep Zoom Composer 匯出結果之後,Exported Data 就值得討論了。Deep Zoom Composer 會以 Name 的設定值(在 Import 工作區),作為存放匯出結果的資料夾名稱(不同匯出類型可以指定不同的資料夾名稱)。

Deep Zoom Composer 的匯出類型有 3 種:Images、Silverlight Deep Zoom、Seadragon Ajax,Deep Zoom Composer 都會替這 3 種類型自動產生相同金字塔影像,不同之處在於 Deep Zoom Composer 會根據不同的技術類型,產生不同的測試頁;例如會替 Silverlight Deep Zoom 產生 Silverlight 應用程式,但 3 種類型都會有放置金字塔影像的 GeneratedImages 資料夾。

以本文為例,匯出類型為 Silverlight Deep Zoom、Name 設定值是 tai,因此在 Exported Data 底下會有 tai 資料夾。在 tai 底下還有 DeepZoomProject、DeepZoomProjectWeb 各一的資料夾,以及 Visual Studio 方案檔、Visual Studio Solution User Options 檔;DeepZoomProject 裡面有 Silverlight 專案的原始程式檔,DeepZoomProjectWeb 裡面則有執行所需的檔案,包括:

  • IIS 應用程式的設定檔 web.config
  • 執行用的網頁 DeepZoomProjectTestPage.html
  • Silverlight 所需的 JavaScript 程式檔 Silverlight.js
  • Silverlight 應用程式包裝檔 DeepZoomProject.xap
  • 放置金字塔影像檔案的資料夾 GeneratedImages

因此縱使沒有圖 7 的交談窗,也可以執行 Deep Zoom Composer 為此專案建立的 Silverlight 應用程式:

Exported Data\tai\DeepZoomProjectWeb\ClientBin\DeepZoomProjectTestPage.html

甚至還可以修改 DeepZoomProjectTestPage.html,以符合自己的需要;檔名也可以改掉,但必須與 GeneratedImages 資料夾和 DeepZoomProject.xap 位於同一目錄,才能執行 Silverlight 應用程式,並載入 GeneratedImages 資料夾裡的圖檔。圖 9 是簡易的修改結果。

圖 9 修改 DeepZoomProjectTestPage.html 的結果

回到首頁


【Deep Zoom Composer 產生的 Silverlight 專案】

Deep Zoom Composer 也會自動產生 Silverlight 方案,包括 Visual Studio 方案檔、XAML 檔、CS 原始檔,現在讓我們以 Visual Studio 2008 來開啟位於 tai 資料夾的 Visual Studio 方案檔 DeepZoomProject.sln。

DeepZoomProject.sln 方案裡有兩個專案:DeepZoomProject 和 DeepZoomProjectWeb,我們現在的焦點是內含這個 Silverlight 應用程式原始檔的後者。DeepZoomProject 專案結構如同一般的 Silverlight 專案,包括了成對的 App.xaml/App.xaml.cs、Page.xaml/Page.xaml.cs,此外還有 12 個 PNG 圖檔,這些是這個 Silverlight 應用程式執行時,右下角 4 個控制鈕 3 種狀態的圖檔。

App.xaml 和 App.xaml.cs 的內容和一般 Silverlight 應用程式類似,在此先不討論,我們要將焦點放在這個 Silverlight 專案的 Page.xaml 和 Page.xaml.cs。

ControlTemplate 製作的控制鈕

首先我們來看 Page.xaml,一開始利用 ControlTemplate 製作了前述在右下角的 4 個控制鈕:

<UserControl x:Class="DeepZoomProject.Page" ......>   
    <UserControl.Resources>   
        <ControlTemplate x:Key="zoomInTemplate" TargetType="Button">   
        ......   
        <ControlTemplate x:Key="zoomOutTemplate" TargetType="Button">   
        ......   
        <ControlTemplate x:Key="homeTemplate" TargetType="Button">   
        ......   
        <ControlTemplate x:Key="fullScreenTemplate" TargetType="Button">   
        ...略...   
    </UserControl.Resources>   
    ...略...   
    <Grid x:Name="LayoutRoot"......>   
        ......   
        <Canvas......>   
            <Button x:Name="zoomIn"......Click="ZoomInClick"/>   
            <Button x:Name="zoomOut"......Click="ZoomOutClick"/>   
            <Button x:Name="goHome" ......Click="GoHomeClick"/>   
            <Button x:Name="fullScreen"......Click="GoFullScreenClick"/>   
        </Canvas>   
    ......

Silverlight 的 Deep Zoom 核心

之所以能在 Silverlight 操作 Deep Zoom 技術的金字塔影像,是因為 MultiScaleImage 類別,這個 Silverlight 專案是在 Page.xaml 以如下的 XAML 加入 MultiScaleImage,其中 Source 指定了金字塔影像的位置:

<MultiScaleImage x:Name="msi" Source="../GeneratedImages/dzc_output.xml"/>

處理滑鼠

滑鼠動作的處理是這個 Silverlight 應用程式的重點,包括指標移動、滾輪以及左鈕的按、放,處理這些動作的程式碼是在 Page.xaml.cs 的 this.MouseMove、MouseWheelHelper、this.MouseLeftButtonDown、this.MouseLeftButtonUp。

例如按下滑鼠左鈕時,在 this.MouseLeftButtonDown 會取得滑鼠指標的 X、Y 軸座標值,也會取得影像區域左上角座標值:

lastMouseDownPos = e.GetPosition(msi);

lastMouseViewPort = msi.ViewportOrigin;

放開滑鼠左鈕時會先檢查是否處於拖曳狀態,如果不是,再檢查是否按著 Shift 鍵:如果按著,放大倍率即為 1/2(也就是縮小一半);如果沒有,放大倍率則為 2(也就是放大一倍)。然後再叫用 Zoom 來處理圖的縮放:

if (!duringDrag)   
{   
bool shiftDown = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;   
double newzoom = zoom;   
  
if (shiftDown)   
{   
    newzoom /= 2;   
}   
else  
{   
    newzoom *= 2;   
}   
  
Zoom(newzoom, msi.ElementToLogicalPoint(this.lastMousePos));   
}

MouseMove 可以處理滑鼠指標移動,但移動不等於正在拖曳,而且拖曳有可能已經持續一陣子了,因此要分別處理:

lastMousePos = e.GetPosition(msi);   
if (mouseDown && !duringDrag)   
    {   
        duringDrag = true;   
        double w = msi.ViewportWidth;   
        Point o = new Point(msi.ViewportOrigin.X, msi.ViewportOrigin.Y);   
        msi.UseSprings = false;   
        msi.ViewportOrigin = new Point(o.X, o.Y);   
        msi.ViewportWidth = w;   
        zoom = 1/w;   
        msi.UseSprings = true;   
    }   
  
    if (duringDrag)   
    {   
        Point newPoint = lastMouseViewPort;   
        newPoint.X += (lastMouseDownPos.X - lastMousePos.X) / msi.ActualWidth * msi.ViewportWidth;   
        newPoint.Y += (lastMouseDownPos.Y - lastMousePos.Y) / msi.ActualWidth * msi.ViewportWidth;   
        msi.ViewportOrigin = newPoint;   
    }

Silverlight 內建並不支援滑鼠滾輪,但 Deep Zoom Composer 自動加入了 MouseWheelHelper 類別:

new MouseWheelHelper(this).Moved += delegate(object sender, MouseWheelEventArgs e)   
{   
e.Handled = true;   
  
double newzoom = zoom;   
  
if (e.Delta < 0)   
    newzoom /= 1.3;   
else  
    newzoom *= 1.3;   
  
Zoom(newzoom, msi.ElementToLogicalPoint(this.lastMousePos));   
msi.CaptureMouse();   
};

處理縮放的是 Page.xaml.cs 裡的 Zoom,實際上是再叫用 MultiScaleImage 類別的:

private void Zoom(double newzoom, Point p)   
{   
    if (newzoom < 0.5)   
    {   
        newzoom = 0.5;   
    }   
    msi.ZoomAboutLogicalPoint(newzoom / zoom, p.X, p.Y);   
    zoom = newzoom;   
}

ZoomAboutLogicalPoint 方法有 3 個參數:第一個參數是縮放倍率,後兩者是縮放位置邏輯座標的 X 和 Y 軸座標值。

回到首頁


【結語】

本文概要說明了 Deep Zoom 技術,並且也提及幾個應用 Deep Zoom 技術的 Silverlight 網站,這些網站相當值得 Deep Zoom 學習者嘗試、參考。要在 Silverlight 應用 Deep Zoom 技術,除了 Visual Studio 2008 和 Expression Blend,Deep Zoom Composer 更是不可或缺的工具,在本文示範的例子,Deep Zoom Composer 不僅能處理 Deep Zoom 所需要的圖形,還能自動產生 Silverlight 應用程式的執行檔和原始程式碼,我們亦可從中瞭解從 Silverlight 控制 Deep Zoom 的基本方式,並直接使用或加以修改後使用。

Deep Zoom 技術的功效當然不只本文所提,例如 Deep Zoom 還能處理影像集合(本文處理的是單一影像),而且這些影像的控制還有許多技巧,都有待學習者進一步瞭解。

【延伸閱讀】

回到首頁


【範例檔案下載】

  • 邊做邊學 Silverlight 2 - Deep Zoom 入門

 

我們在乎每一位開發人員的感受 : 到 (Twitter) 公開您的想法 到 (論壇) 公開您的想法 寫悄悄話告訴我們

回到首頁

Microsoft 正展開一份線上問卷調查,了解您對於網站的看法。如果您選擇參加,您離開網站時即會顯示線上問卷調查。

您是否想要參加?