使用 Scalable Vector Graphics 為 ASP.NET 構建基於 XML 的靈活、輕量的映像

來源:互聯網
上載者:User

Dennis Forbes

本文假設您熟悉 HTML、ASP.NET 和 C#

下載本文的代碼:ScalableVectorGraphics.exe (123KB)

摘要

Scalable Vector Graphics (SVG) 是圍繞 XML 建立的 W3C 圖形標準,它是使快速輕量圖(比表和圖形)能在適當的查看器上迅速呈現的幾種向量圖形技術之一。這樣的向量圖形有許多優勢,包括節省頻寬和儲存媒體、靈活性強。本文將解釋這些優點,並向您介紹如何輕鬆地在 Web 應用程式中添加強大、動態和互動可視化元素。

Scalable Vector Graphics (SVG) 是使用 XML 文檔製作和部署二維向量圖形的一種標準。它是由大量業界組織制訂和認可的 WWW 聯合會 (W3C) 建議。SVC 具有高品質且豐富的向量圖形、簡單性及 XML 基礎廣泛的工具相容性,以及功能豐富的文件物件模型 (DOM) 介面的動力,從而為 DHTML 項目帶來了強大的新成員。將它與創造力(以及一點別出心裁)相結合,就可以使無數的互動式 Web 可能變為現實,從而改善您的 Web 應用程式的外觀、可用性和功能性。

各種向量圖形格式

向量圖形(包括 SVG、Vector Markup Language (VML)、Windows 圖元檔案(.wmf 和 .emf)和 TrueType 字型)是以指令列表的形式儲存和表述的,這些指令詳細描述了如何使用一連串的形狀、線和轉換來重新建立映像。這種做法好比通過準確記錄、然後重新建立原先用來產生繪圖的筆刷筆觸序列來複製該繪圖。向量圖形通常資料量很小(特別是當它經過壓縮後),所以最大程度地降低了對儲存空間和頻寬的要求。當它們列印或縮放,甚至是擴大或放大時,都不需要像素化就能呈現。因為允許將它們分解為基本的形狀和曲線,所以對於製作精度有限的任何圖形是一種很好的選擇。但另一方面,因為重新建立一幅映像需要的步驟是數以千計的,所以呈現向量圖形需要的計算量很大。向量圖形一般不適合表示實際拍攝、高度細節化的映像,但通常很適合表示由基本形狀組成的圖形、圖表或者映像(比如卡通風格的映像)。

點陣圖形 — 例如可移植網狀圖形 (PNG)、GIF 和 JPEG — 是通過對以特定的解析度和縮放比例預先呈現的、最終映像的逐像素的表示方式進行比較而繪製的。這好比等待繪圖完成,然後以特定用途和輸出裝置需要的解析度和大小將它畫下。光柵映像很容易跨平台移植,可以最大程度地降低對計算量的要求。它們用於表示高度細節化的、實際拍攝的映像是很理想的,但通常縮放和列印的效果較差。因為沒有對龐大的檔案大小進行處理,所以它們的動態可程式化性很差,而且通常儲存和傳輸的效率很低。

細心的讀者可能已經注意到本部分前面提到的 VML,的確有必要對它進行詳細介紹:VML 具備 SVG 的許多同樣的優點,如輕鬆的基於文本製作和根據向量圖形構建的基礎。然而,其他格式極為排斥 VML,而 SVG 在去年獲得了一些 VML 的向量圖形要素。有工具可以在 SVG 和 VML 之間進行雙向轉換,所以可以相信經過很小的努力就可以使這兩者同時得到支援。

SVG 入門

一個 SVG 實質上是一個 XML 文檔,這種文檔遵循定義為 SVG 批准進程的一部分的架構。規範中定義的是各種基本幾何形狀,例如矩形、圓、橢圓、直線、折線、多邊形和字形元素(例如文本)。複雜些的形狀可以使用路徑元素建立,允許您定義諸如一連串直線、弧線和複雜的貝賽爾曲線等形狀。使用這些基本形狀,外加一點巧妙設計,即使最複雜的幾何結構都可以建立出來。圖 1 闡述了一個基本的 SVG 文檔的 XML 構成,圖 2 顯示在 SVG 查看器中呈現的 SVG 的樣子。

圖 2 查看器中的 SVG

雖然有些應用程式(例如 CorelDraw、Adobe Illustrator 和 Batik SVG 工具集)可以直接顯示或處理 SVG,但在大多數情況下,SVG 可以作為 HTML 文檔的一種元素使用,與其他 HTML 文本和多媒體內容共存。典型方法是通過原始的嵌入標記加以實現:

<html><body><h1>A Page Containing an SVG</h1><embed name="ExampleSVG"pluginspage="http://www.adobe.com/svg/viewer/install/"src="figure1.svg" width="400" height="300"type="image/svg-xml" /></body></html>

pluginspage 屬性可將使用者引向可用的內容處理常式(如果還沒安裝)。在本樣本中,我引用的是 Adobe SVG Viewer。

值得注意的地方是嵌入標記的 width 和 height 屬性之間的相關性,對於所引用圖形中的根 SVG 元素也是一樣(這個值有時會以各種方式表示,包括像素、厘米等等)。如果這些數字不匹配,所封裝的圖形就會以某種不合要求的方式被裁剪或修改。通常使用的一種可避免這種問題並提供更大的靈活性的技術就是防止將該 SVG 限制為特定的大小。圖 3 顯示了一個經過稍加修改的 SVG,它使用 viewBox 屬性,而不是 width 和 height。它固定了繪畫時的畫板邊界,並因此固定了 width 和 height 之間的比例;然而,它並不固定呈現大小。如果您更改了嵌入元素的 width 和 height,但保持 width 和 height 的相對比例不變,則 SVG 圖形就會依此平滑改變大小。

該非標準 HTML 嵌入元素的一種替代方案(特別是當要求與 XHTML 相容)就是使用對象或 iframe 元素:

<html><body><object data="figure1.svg"codetype="image/svg-xml"style="width:400;height:300;"></object><iframe src="figure3.svg" width="600" height="450" /></body></html>

因為當遇到不支援的類型時允許層疊 (cascade),這種對象標記提供了一個特彆強大的功能。例如,以下文檔告訴瀏覽器首先試著呈現 SVG,如果失敗(例如,SVG 功能不可用),就顯示備選的光柵 PNG。這樣的結構允許建立同時支援 SVG 和光柵內容的單個頁面集,而不需要根據用戶端瀏覽器的能力而有不必要的分支,如下所示:

<html><body><object data="figure1.svg" codetype="image/svg-xml"style="width:400;height:300;"><img src="figure1.png" width="400" height="300" /></object></body></html>

關於對象標記有一點告誡需要說明。在開發 Microsoft Internet Explorer 時,Microsoft 致最大的努力使它具有很高的可擴充性。這表現在瀏覽器執行個體化大量關聯程式組件以顯示多媒體 Web 頁面的能力上(通過在 HTML 上直接引用,例如通過 CODEBASE/CLASSID 對引用特定的 ActiveX 對象,或者通過 MIME 類型並尋找 HKEY_CLASSES_ROOT\MIME\Database\Content Type)。這帶來了極大的通用性,但是當有惡意的應用程式劫持內容類型並導致適時不能正確呈現時,或者當它們在卸載時不能將 Internet Explorer 重新關聯為處理常式時,就會產生問題。另外,當我將對象標記和 SVG 一起使用時遇到一些不一致和不規則的問題 — 當使用嵌入標記或 iframe 標記時不會有這樣的問題。然而,嵌入標記將不被支援。通常,您的用途可能會有不同,但是當您解決用戶端安裝大量輔助應用程式的棘手情況時,應該記住這個告誡。

動態內容

SVG 的一個強大功能就是具有通過內部或外部指令碼以編程方式操作 SVG 的圖形元素的能力。圖 4是一個封裝了 figure3.svg 圖形的 HTML 文檔(可從位於本文頂部的連結處的下載檔案中獲得)。本樣本使用適用於 Internet Explorer 的 Adobe SVG Viewer 外掛程式。本樣本說明為了自動操作由 SVG 查看器公開的 DOM 介面,在用作容器的 HTML 文檔中 ECMAScript (JavaScript) 的用法。通過單擊如 5 所示的 Web 頁面中的一個按鈕,使用者可以切換在基本形狀中使用的顏色或者控制一組對象的旋轉速度。但是這個特例顯示的只是經過改頭換面的不提倡使用的 BLINK 標記,它的確暗示 SVG提供的可能性非常廣泛。可以在圖形中添加新的對象,也可以完全修改現有的內容。這就允許您建立用動態解釋提示支援的圖形,例如,給使用者一個更好的工具以協助他完全理解資訊。

圖 5 操作形狀

SVG 部署

因為 SVG 的尖端特性以及缺少當前所有主流瀏覽器的本地支援,所以 Web 網站訪問者通常需要下載和安裝專用的查看器(比如 Adobe SVG Viewer 或即將推出的 Corel SVG Viewer)才能看到 Web 頁面內的 SVG 內容(這種狀況至少要持續到瀏覽器像支援大多數其他圖形格式一樣本身就本地支援 SVG 時為止)。Adobe Viewer 本身可在幾種平台上運行,包括 Windows、Macintosh 和 Linux,以及幾乎所有主流 網頁瀏覽器。考慮到 SVG 是一個經廣泛證明的標準,所以我感覺它並不是對一種專用格式悄悄下的一場賭注,而是為將來能夠發揮積極的作用而在目前所作的一種投資。

儘管安裝了 SVG 的用戶端普及得很廣泛,但大多數網站仍需要繼續支援可能無法安裝 SVG 特定的軟體的舊式用戶端。通過可以產生 SVG(同時又能為舊式用戶端建立靜態點陣圖形)的圖形基礎結構可以輕鬆實現這樣的解決方案。本文後面將詳細介紹能實現這種目的的一種強大方法。當然,即使 SVG 從不直接服務於 網頁用戶端,也可以在後端將 SVG 與 Microsoft .NET Framework 中強大的 XML 類結合使用。

迅速建立 SVG

VG 的傑出圖形能力與 NET Framework 的包羅永珍的功能集相結合為 Web 開發人員提供了很好的機會。通過利用資料後端與自動的 SVG 文檔建立,Web 網站可以提供即時、美觀、互動圖形,協助使用者更好地領會和理解資訊。還能使 Web 應用程式有一個更加專業、優美的外觀。

為了使根 SVG 文檔的動態建立更為輕鬆,同時為了示範具有基本 SVG 智能的 XmlDocument 衍生類別,我建立了一個很普通的類, 6 所示。以下的樣本將用到這個助手類,它應該與放在 Web 應用程式的 bin 目錄(例如,C:\inetpub\wwwroot\bin)中的結果 DLL 一起編譯:

csc /target:library figure5.cscopy figure5.dll C:\inetpub\wwwroot\bin

圖 7 顯示了一個由 SVG 產生的 Web 頁面的基礎。它包含一個簡單的伺服器端 ASP.NET 指令碼,這個指令碼通過返回包含以 ISO 8601 格式表示的目前時間的 SVG 文檔來響應請求。儘管這個樣本的實用性有限,但它的確顯示了在伺服器中動態建立 SVG 文檔的簡單性。這個樣本對字串進行串連以形成 XML 文檔。它也可以通過以編程方式添加每個使用恰當 DOM 方法的元素和屬性來實現。這個樣本設定了 Response 對象的 ContentType 屬性(它也可以使用 @Page 指令的 ContentType 屬性)。這可以使用戶端不用依靠煩瑣且不可靠的副檔名就可以識別內容類型。儘管如此,有時在 URL 中包含一個假的參數尾碼(例如 ?.svg)是有好處的,因為用戶端(例如 Opera 6)會盲目地尋找一個副檔名以確定內容類型。

本樣本還有一點值得注意的是 XML 文檔直接串流到輸出資料流,中途沒有任何不必要的駐留,從而保持了高效能。當頁面需要滿足大量使用者的即時需要時,這就十分值得考慮了。

接下來是一個在調用 ASP.NET 頁的過程中產生的結果 SVG,以及帶有取決於何時調用頁面的日期/時間:

<?xml version="1.0" standalone="yes"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN""http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"[]><svg width="400" height="200" xmlns="http://www.w3.org/2000/svg"><text x="100" y="100" font-family="Verdana" font-size="15"fill="blue">2003-03-28T122002-10-29T12:02:14</text></svg>

如前面所述,可以使用對象標記將這個動態 SVG 文檔包含在一個基本的 HTML 頁面中:

<html><body><center><h1>SVG Test</h1><object name="ExampleSVG" codebase="http://www.adobe.com/svg/viewer/install/" data="figure7.aspx?.svg" width="400" height="200"type="image/svg+xml"/></center></body></html>

採用SVG 繪圖

許多 SVG 可以按要求根據資料庫中資料的更改動態產生,包含地區性邊界和劃分或最新的月份銷售數額的 GIS 資訊就是極好的例子。作為通過資料動態產生 SVG 文檔的技術樣本,命名空間 yafla.yaflaSVG(通過本文頂部的連結獲得 svg_graphing.zip,並編譯和安裝其中的 yafla.yaflaSVG.cs 檔案就可以使用該命名空間)提供了各種類來協助將資料轉化成圖形。這些圖形類型包括餅圖(參見 8)以及垂直和水平橫條圖(參見 9)。該類階層已經以一種容易擴充的物件導向方式進行構建,並提供大量設定來控制產生的圖形的 UI。既然產生的 SVG 圖形是以 XML 文檔的形式返回的,則在將文檔返回給調用者之前,可以利用 .NET Framework 中豐富的 XML 能力對它們進行修改。雖然這些圖形無法取代商業畫圖產品,但它們是 SVG 系列中優秀的入門級產品,能實際為一些讀者提供切實可行的解決方案。Barchart_example.aspx 和 piechart_example.aspx(也在下載中提供)示範了使用這些類動態產生圖形的基礎知識(這裡建立的是橫條圖和餅圖)。雖然這些樣本是用手動方式建立和填充 DataTable 的,但這與作為查詢結果檢索 DataTable 的方式一樣簡單,因此實現了真正的動態向量圖形。

圖 8 餅圖

節省頻寬

雖然 SVG 文檔通常比相應的點陣圖形小了許多,但當表示基本圖形和圖表時,XML 的固有詳細特性還是會為複雜圖形產生很大的檔案。幸運的是,SVG 標準包含對 GZIP 壓縮(在 RFC 1952 中經證明的標準)的本地支援,從而極大減少了傳輸和儲存大小 — 通常壓縮率達到 80% 或更多。雖然 GZIP 因為壓縮和解壓縮而確實增加了一些額外的計算開銷,但在伺服器端通過適當的緩衝能夠得以緩解。在用戶端,這種擔心很大程度上就沒有必要了,因為現代高效能處理器的速度遠遠超過了大多數網路連接的速度。考慮到這些因素,可以很明顯地看出,壓縮是一舉兩得,既能降低主機的頻寬成本,又能給用戶端一個更快更靈活的 Web 網站。

圖 9 橫條圖

對於靜態 SVG 文檔,壓縮是很簡單的,只需對伺服器端的檔案進行 GZIP 操作(經過壓縮後得到的檔案的副檔名是 .svgz;.svg 是未壓縮的 SVG 文檔的副檔名),確保在 Microsoft Internet 資訊服務 (IIS) 中將 .svg 和 svgz 與適當的 MIME 類型 (image/svg+xml) 相關聯,並確保引用指向壓縮過的副本。通過這樣就可以只用到原來所需頻寬的一小部分。您的用戶端,特別是撥接的 Internet 使用者,會喜歡更快速的體驗。

壓縮動態產生的內容時會稍微複雜一點。進行動態壓縮的第一步是確定它是否已經產生。您的 Web 環境能否將壓縮過的輸出資料流式傳送到安裝有相應解壓縮裝置的用戶端? 10 是一個簡單的指令碼,它將 URL 作為參數(例如,wscript figure9.js http://127.0.0.1/mydynamicpage.aspx)並使用 MSXML ServerXMLHTTP 對象來報告:對於該 URL 而言,是否支援流式傳送壓縮內容。另外一個優點是,它還報告了伺服器返回給請求的 MIME 類型,通過這樣來讓您確認伺服器是否正確配置。進行測試很重要,因為壓縮可以通過負載平衡前端或 IIS ISAPI 篩選器(收到請求時壓縮輸出)透明地進行,在這樣的情況下,雙重壓縮就是沒有必要的浪費。

如果您想要啟用動態 SVG 壓縮,在市場上有各種 NET 可訪問的壓縮組件,包括功能豐富、使用可靠的商業軟體包、用於現有 DLL 的 COM Interop 封裝,以及優秀的開放原始碼項目。這些解決方案有許多實現為從 .NET 流對象派生的類,這樣在使用流對象的地方就可以很容易地使用。從示範角度考慮,我選擇的是採用 C# 編寫、開放原始碼的 SharpZipLib 庫,可在http://www.icsharpcode.net/OpenSource/SharpZipLib下載。

將二進位的 DLL 放入全域組件快取或 Web 應用程式的 /bin 目錄後,就可以十分容易地實現流式傳送 GZIP 壓縮內容, 11所示(它是圖 7 的變體)。通過使用 GZIP 流介面作為 XML 文檔和 HTTP 響應對象之間的傳輸橋樑,資料就可以在發送的時候壓縮,這樣極大地降低了頻寬需求。對於如此小的 SVG 文檔,GZIP 壓縮所節省的頻寬是很小的,與增加的計算成本相比很可能得不償失。然而,對於實際使用的文檔,它所帶來的好處可能非常大。Compressed_ barchart_example.aspx(下載中提供)對圖表組件使用壓縮。在該樣本中,文檔從 7,722 降到 1,235 位元組(減少了 84%)。

保持向後相容

期待每個使用者都採用專用於您的 Web 網站的特定組件來升級他們的系統是不現實的。使用深奧的技術會因為使用者擔心被排除在外而導致無數支援電話,或者對於公用 Web 網站,不可避免會有大量電子郵件來自極個別對 HTML 1.0 以後的一切都很狂熱的擁護者。為了避免這種情況,一種可能就是在伺服器上將 SVG 呈現為位元影像化的圖形,並向支援的用戶端返回 SVG 本身,而對其他用戶端返回位元影像化的圖形。如果 SVG 本身從不服務於用戶端,這種方法是可行的,但僅僅是作為動態圖形製作技術使用,它需要進行光柵化才能呈現。

捕獲它的 GDI 輸出以進行光柵化所需要的計算量可想而知。但是 Adobe SVG Viewer 能否用於在伺服器端呈現在它們的許可協議中可能會提到,可以訪問http://www.adobe.com來核實。另一個可行的辦法是採用 Batik 項目 (http://xml.apache.org/batik/svgrasterizer.html),這個工具 + 生產力可以將 SVG 轉換成各種格式,包括 PNG、TIFF、PDF 或 JPEG 等光柵格式(雖然有損耗的 JPEG 格式通常只適合實際拍攝的映像或具有平滑的顏色過渡的映像)。GIF 格式從它的輸出格式排除大概是因為相關的許可問題。不幸的是,Batik 需要您將 SVG 儲存到硬碟(如臨時檔案夾)中,然後它在那裡進行處理並根據傳遞的參數產生點陣圖形。Barchart_example_rasterize.aspx(下載中提供)示範了如何攜帶 width 輸入參數並通過它產生期望大小的光柵 PNG 橫條圖(例如,http://localhost/barchart_example_rasterize.asp?width=750)。添加附加邏輯以攜帶一個可以選擇目標檔案類型並允許產生各種類型和大小的圖形輸出的參數是很容易做的。比較棘手的情況是添加邏輯以將緩衝整合到系統中。這種情況需要將 SVG 本身和一個只要源 SVG 更改就會重建的附屬點陣圖形儲存到緩衝對象中(即使只是短期儲存)。通過這樣的更改就可以啟用一個功能強大的伺服器端圖形子系統,它可以滿足動態向量和光柵二者的需要,同時又能使用 .NET Framework 的緩衝基礎結構,在即使負載很高的情況下,也可實現很大的伸縮性和很短的回應時間。

出於效能和整合考慮,開發一個 .NET 本地 SVG 光柵化器 (rasterizer) 是一個很好的選擇;但此項目不在本文的討論範圍內。也許隨著 SVG 得到越來越多的關注,實現這一點會成為現實。SVG 目前也缺少 DHTML 行為(而 VML 支援)。這將會是另一個添加到 SVG 規範的很好的領域。

小結

通過將 SVG 的圖形威力和 .NET Framework 的強大功能與通用性相結合,您可以將 Web 應用程式變成一個處理圖形的無敵金剛。通過添加動態圖形元素,您可以使資料更加清晰,實現更好的組織圖化支援,並向外界展示更加完美、更加專業的映像。希望本文能夠提供足夠的資訊以滿足您的需要,並能鼓勵您在 Web 開發中更進一步體驗和探索向量圖形令人激動的實現可能。

相關文章請參閱:How to use VML on Web Pages
Create Snazzy Web Charts and Graphics On the Fly with the .NET Framework
Manipulate XML Data Easily with Integrated Readers and Writers in the .NET Framework
背景資料請參閱:
http://www.w3.org/TR/SVG
http://www.w3.org/TR/NOTE-VML
http://www.w3c.org/Graphics/WebCGM

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.