在 ASP.NET 網頁 (Razor) 網站中處理影像
演講者:Tom FitzMacken
本文向您展示如何在 ASP.NET 網頁 (Razor) 網站中新增、顯示和操作影像 (調整大小、翻轉和新增浮水印)。
您將學到什麼:
- 如何動態新增影像到頁面。
- 如何讓用戶上傳影像。
- 如何調整影像大小。
- 如何翻轉或旋轉影像。
- 如何為影像添加浮水印。
- 如何使用影像作為浮水印。
這些就是本文介紹的 ASP.NET 程式設計功能:
WebImage
協助程式。Path
物件提供了可讓您操作路徑和檔案名稱的方法。教學中使用的軟體版本
- ASP.NET 網頁 (Razor) 2
- WebMatrix 2
本教學也適用於 WebMatrix 3。
動態新增圖片到網頁
在開發網站時,您可以將影像新增至您的網站和各個頁面。 您還可以讓用戶上傳影像,這對於讓他們添加個人資料照片等任務可能很有用。
如果您的網站上已有影像,並且您只想將其顯示在頁面上,則可以使用以下 HTML <img>
元素:
<img src="images/Photo1.jpg" alt="Sample Photo" />
但有時,您需要能夠動態顯示影像 - 也就是說,在頁面執行之前您不知道要顯示什麼影像。
本節中的程序顯示如何動態顯示影像,其中使用者從影像名稱清單中指定影像檔案名稱。 他們從下拉清單中選擇影像的名稱,當他們提交頁面時,就會顯示他們選擇的影像。
在 WebMatrix 中,建立一個新網站。
新增一個名為 DynamicImage.cshtml 的新頁面。
在網站的根資料夾中,新增一個新資料夾並將其命名為影像。
將四個影像新增到您剛剛建立的影像資料夾中。 (您手邊的任何影像都可以,但它們應該適合頁面。) 將影像重新命名為 Photo1.jpg、Photo2.jpg、Photo3.jpg 和 Photo4.jpg。 (在此過程中您不會使用 Photo4.jpg,但您將在本文後面使用它。)
驗證這四個影像未標記為唯讀。
將頁面中的現有內容替換為以下內容:
@{ var imagePath= ""; if( Request["photoChoice"] != null){ imagePath = @"images\" + Request["photoChoice"]; } } <!DOCTYPE html> <html> <head> <title>Display Image on the Fly</title> </head> <body> <h1>Displaying an Image On the Fly</h1> <form method="post" action=""> <div> I want to see: <select name="photoChoice"> <option value="Photo1.jpg">Photo 1</option> <option value="Photo2.jpg">Photo 2</option> <option value="Photo3.jpg">Photo 3</option> </select> <input type="submit" value="Submit" /> </div> <div style="padding:10px;"> @if(imagePath != ""){ <img src="@imagePath" alt="Sample Image" width="300px" /> } </div> </form> </body> </html>
頁面主體有一個名為
photoChoice
的下拉清單 (<select>
元素)。 此清單具有三個選項,每個清單選項的value
屬性都有您放入影像資料夾中的影像之一的名稱。 本質上,該清單允許使用者選擇一個友善的名稱,例如「照片 1」,然後在提交頁面時傳遞 .jpg 檔案名稱。在程式碼中,您可以透過讀取
Request["photoChoice"]
從清單中獲取使用者的選擇 (換句話說,影像檔案名稱)。 你先看看是否有選擇。 如果存在,則為影像建立一個路徑,該路徑由影像資料夾的名稱和使用者的影像檔案名稱組成。 (如果您嘗試建置路徑但Request["photoChoice"]
中沒有任何內容,則會收到錯誤。) 這會產生以下相對路徑:圖片/Photo1.jpg
該路徑儲存在名為
imagePath
的變數中,稍後您將在頁面中需要該變數。在正文中,還有一個用於顯示使用者選擇的影像的
<img>
元素。src
屬性未設定為檔案名稱或 URL,就像顯示靜態元素一樣。 相反,它被設定為@imagePath
,這意味著它從您在程式碼中設定的路徑獲取其值。但是,當頁面第一次執行時,沒有可顯示的影像,因為使用者尚未選擇任何內容。 這通常代表
src
屬性將為空,並且影像將顯示為紅色「x」(或瀏覽器在找不到影像時呈現的任何內容)。 為了防止這種情況,您可以將<img>
元素放入一個if
區塊中,以測試imagePath
變數中是否包含任何內容。 如果使用者做出選擇,則imagePath
包含路徑。 如果使用者沒有選擇影像或這是第一次顯示頁面,則<img>
元素甚至不會呈現。儲存檔案並在瀏覽器中執行該頁面。 (在執行頁面之前,請確保在檔案工作區中選擇該頁面。)
從下拉清單中選擇影像,然後按一下範例影像。 確保您針對不同的選擇看到不同的影像。
上傳圖片
前面的範例向您展示如何動態顯示影像,但它僅適用於您網站上已有的影像。 此過程示範如何讓使用者上傳影像,然後將其顯示在頁面上。 在 ASP.NET 中,您可以使用協助程式即時操作影像,WebImage
協助程式具有可讓您建立、操作和保存影像的方法。 WebImage
說明程式支援所有常見的 Web 映像檔類型,包括 .jpg、.png 和 .bmp。 在本文中,您將使用 .jpg 影像,但您可以使用任何影像類型。
新增一個頁面並將其命名為 UploadImage.cshtml。
將頁面中的現有內容替換為以下內容:
@{ WebImage photo = null; var newFileName = ""; var imagePath = ""; if(IsPost){ photo = WebImage.GetImageFromRequest(); if(photo != null){ newFileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(photo.FileName); imagePath = @"images\" + newFileName; photo.Save(@"~\" + imagePath); } } } <!DOCTYPE html> <html> <head> <title>Image Upload</title> </head> <body> <form action="" method="post" enctype="multipart/form-data"> <fieldset> <legend> Upload Image </legend> <label for="Image">Image</label> <input type="file" name="Image" /> <br/> <input type="submit" value="Upload" /> </fieldset> </form> <h1>Uploaded Image</h1> @if(imagePath != ""){ <div class="result"> <img src="@imagePath" alt="image" /> </div> } </body> </html>
文字正文有一個
<input type="file">
元素,可讓使用者選擇要上傳的檔案。 當他們點擊提交時,他們選擇的文件將與表單一起提交。要取得上傳的影像,您可以使用
WebImage
協助程式,它具有各種有用的影像處理方法。 具體來說,您用於WebImage.GetImageFromRequest
獲取上傳的影像 (如果有) 並將其儲存在名為photo
的變數中。此範例中的許多工作涉及獲取和設定檔案名稱和路徑名。 問題是您想要取得使用者上傳的映像的名稱 (並且只是名稱),然後為要儲存映像的位置建立新路徑。 由於使用者可能會上傳多個具有相同名稱的影像,因此您可以使用一些額外的程式碼來建立唯一的名稱並確保使用者不會覆蓋現有圖片。
如果影像實際上已上傳 (測試
if (photo != null)
),您可以從影像的FileName
屬性中取得影像名稱。 當使用者上傳影像時,FileName
包含使用者的原始名稱,其中包括來自使用者電腦的路徑。 它可能看起來像這樣:C:\Users\Joe\Pictures\SamplePhoto1.jpg
不過,您不需要所有路徑資訊 — 您只需要實際的檔案名稱 (SamplePhoto1.jpg)。 您可以使用
Path.GetFileName
方法僅從路徑中刪除文件,如下所示:Path.GetFileName(photo.FileName)
然後,您可以透過向原始名稱新增 GUID 來建立新的唯一檔案名稱。 (關於 GUID 的更多資訊,請參閱本文後面的關於 GUID。) 然後建立可用於保存影像的完整路徑。 保存路徑由新檔案名稱、資料夾 (影像) 和目前網站位置組成。
注意
為了使您的程式碼將檔案保存在影像資料夾中,應用程式需要該資料夾的讀寫權限。 在您的開發電腦上,這通常不是問題。 但是,當您將網站發佈到託管提供者的 Web 伺服器時,您可能需要明確設定這些權限。 如果您在託管提供者的伺服器上執行此程式碼並收到錯誤,請與託管提供者聯絡以了解如何設定這些權限。
最後,將保存路徑傳遞給
WebImage
協助程式的Save
方法。 這會將上傳的影像儲存在新名稱下。 保存方法如下圖所示:photo.Save(@"~\" + imagePath)
。 完整路徑附加到@"~\"
,即目前網站位置。 (有關~
運算子的資訊,請參閱使用 Razor 語法的 ASP.NET Web 程式設計簡介。)與前面的範例一樣,頁面正文包含一個用於顯示影像的
<img>
元素。 如果imagePath
已設置,則呈現<img>
元素並將src
屬性設為imagePath
值。在瀏覽器中執行該頁面。
上傳影像並確保其顯示在頁面中。
在您的網站中,打開影像資料夾。 您會看到新增了一個文件,其文件名稱如下所示:
45ea4527-7ddd-4965-b9ca-c6444982b342_MyPhoto.png
這是您上傳的影像,其名稱前面帶有 GUID。 (您自己的檔案將具有不同的 GUID,並且名稱可能與 MyPhoto.png 不同。)
提示
關於 GUID
GUID (全域唯一 ID) 是一種標識符,通常以下列格式呈現:936DA01F-9ABD-4d9d-80C7-02AF85C822A8
。 每個 GUID 的數字和字母 (從 A-F) 都不同,但它們都遵循使用 8-4-4-4-12 個字元組的模式。 (從技術上講,GUID 是一個 16 位元組/128 位元數字。) 當您需要 GUID 時,可以呼叫為您產生 GUID 的專用程式碼。 GUID 背後的想法是,在數字的巨大尺寸 (3.4 x 1038) 和產生它的演算法之間,幾乎可以保證產生的數字是獨一無二的。 因此,當您必須保證不會兩次使用相同的名稱時,GUID 是為事物產生名稱的好方法。 當然,缺點是 GUID 對使用者來說不是特別友好,因此當名稱僅在程式碼中使用時往往會使用它們。
調整影像大小
如果您的網站接受使用者提供的影像,您可能需要在顯示或儲存影像之前調整影像的大小。 您可以再次使用 WebImage
協助程式來執行此操作。
此過程示範如何調整上傳影像的大小以建立縮圖,然後將縮圖和原始影像保存在網站中。 您在頁面上顯示縮圖並使用超連結將使用者重新導向到全尺寸影像。
新增一個名為 Thumbnail.cshtml 的新頁面。
在影像資料夾中,建立一個名為縮圖的子資料夾。
將頁面中的現有內容替換為以下內容:
@{ WebImage photo = null; var newFileName = ""; var imagePath = ""; var imageThumbPath = ""; if(IsPost){ photo = WebImage.GetImageFromRequest(); if(photo != null){ newFileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(photo.FileName); imagePath = @"images\" + newFileName; photo.Save(@"~\" + imagePath); imageThumbPath = @"images\thumbs\" + newFileName; photo.Resize(width: 60, height: 60, preserveAspectRatio: true, preventEnlarge: true); photo.Save(@"~\" + imageThumbPath); } } } <!DOCTYPE html> <html> <head> <title>Resizing Image</title> </head> <body> <h1>Thumbnail Image</h1> <form action="" method="post" enctype="multipart/form-data"> <fieldset> <legend> Creating Thumbnail Image </legend> <label for="Image">Image</label> <input type="file" name="Image" /> <br/> <input type="submit" value="Submit" /> </fieldset> </form> @if(imagePath != ""){ <div class="result"> <img src="@imageThumbPath" alt="Thumbnail image" /> <a href="@Html.AttributeEncode(imagePath)" target="_Self"> View full size </a> </div> } </body> </html>
此程式碼與前面範例中的程式碼類似。 不同之處在於,此程式碼會保存影像兩次,一次正常保存,一次在建立影像的縮圖副本後保存。 首先,您獲取上傳的影像並將其保存在影像資料夾中。 然後,您為縮圖建立一個新路徑。 若要實際建立縮圖,您可以呼叫
WebImage
協助程式的Resize
方法來建立 60 像素 x 60 像素的影像。 此範例顯示如何保留縱橫比以及如何防止影像放大 (以防新尺寸實際上會使影像變大)。 調整大小的影像然後保存在縮圖子資料夾中。在標記的末尾,您可以使用前面範例中看到的具有動態
src
屬性的相同<img>
元素來有條件地顯示影像。 在這種情況下,您將顯示縮圖。 您也可以使用<a>
元素建立指向影像大版本的超連結。 與<img>
元素的src
屬性一樣,您可以將href
元素的<a>
屬性動態設定為imagePath
中的任何內容。 為了確保該路徑可以用作 URL,您可以傳遞imagePath
方法,Html.AttributeEncode
方法將路徑中的保留字元轉換為 URL 中可以使用的字元。在瀏覽器中執行該頁面。
上傳照片並驗證是否顯示縮圖。
點擊縮圖可查看全尺寸影像。
在影像和縮圖/縮圖中,請注意已新增檔案。
旋轉和翻轉影像
WebImage
協助程式還可以讓您翻轉和旋轉影像。 此過程示範如何從伺服器取得影像,將影像上下翻轉 (垂直),儲存,然後在頁面上顯示翻轉的影像。 在此範例中,您僅使用伺服器上已有的檔案 (Photo2.jpg)。 在真實的應用程式中,您可能會翻轉動態獲取其名稱的影像,就像在前面的範例中所做的那樣。
新增一個名為 FlipImage.cshtml 的新頁面。
將頁面中的現有內容替換為以下內容:
@{ var imagePath= ""; WebImage photo = new WebImage(@"~\Images\Photo2.jpg"); if(photo != null){ imagePath = @"images\Photo2.jpg"; photo.FlipVertical(); photo.Save(@"~\" + imagePath); } } <!DOCTYPE html> <html> <head> <title>Get Image From File</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> </head> <body> <h1>Flip Image Vertically</h1> @if(imagePath != ""){ <div class="result"> <img src="@imagePath" alt="Image" /> </div> } </body> </html>
程式碼使用
WebImage
協助程式從伺服器取得影像。 您可以使用先前範例中用於保存影像的相同技術來建立影像的路徑,並在使用WebImage
建立映像時傳遞該路徑:WebImage photo = new WebImage(@"~\Images\Photo2.jpg");
如果找到影像,您將建構一個新的路徑和檔案名,就像在前面的範例中所做的那樣。 若要翻轉影像,請呼叫
FlipVertical
方法,然後再次儲存影像。透過使用
src
屬性設定為imagePath
的<img>
元素,影像再次顯示在頁面上。在瀏覽器中執行該頁面。 Photo2.jpg 的影像是上下顛倒顯示的。
重新整理頁面或再次要求頁面即可看到影像再次正面朝上翻轉。
要旋轉影像,您可以使用相同的程式碼,只不過您不呼叫 FlipVertical
或 FlipHorizontal
,而是呼叫 RotateLeft
或 RotateRight
。
向影像添加浮水印
將影像新增至網站時,您可能需要在儲存影像或將其顯示在頁面上之前向影像添加浮水印。 人們經常使用浮水印將版權資訊添加到影像中或宣傳他們的企業名稱。
新增一個名為 Watermark.cshtml 的新頁面。
將頁面中的現有內容替換為以下內容:
@{ var imagePath= ""; WebImage photo = new WebImage(@"~\Images\Photo3.jpg"); if(photo != null){ imagePath = @"images\Photo3.jpg"; photo.AddTextWatermark("My Watermark", fontColor:"Yellow", fontFamily: "Arial"); photo.Save(@"~\" + imagePath); } } <!DOCTYPE html> <html> <head> <title>Water Mark</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> </head> <body> <h1>Adding a Watermark to an Image</h1> @if(imagePath != ""){ <div class="result"> <img src="@imagePath" alt="Image" /> </div> } </body> </html>
此程式碼類似於先前 FlipImage.cshtml 頁面中的程式碼 (儘管這次它使用 Photo3.jpg 檔案)。 若要新增浮水印,請在儲存影像之前呼叫
WebImage
協助程式的AddTextWatermark
方法。 在對AddTextWatermark
的呼叫中,您傳遞文字「My Watermark」,將字體顏色設為黃色,並將字體系列設為 Arial。 (雖然此處未顯示,但此WebImage
協助程式還允許您指定不透明度、字體系列和字體大小以及水印文字的位置。) 儲存影像時,它不能是唯讀的。如您之前所見,影像是透過使用 src 屬性設定為
<img>
的元素顯示在頁面上的@imagePath
。在瀏覽器中執行該頁面。 請注意影像右下角的文字「我的浮水印」。
使用影像作為浮水印
您可以使用其他影像,而不是使用文字作為浮水印。 人們有時會使用公司徽標等影像作為浮水印,或使用浮水印影像而不是文字來獲取版權資訊。
新增一個名為 ImageWatermark.cshtml 的新頁面。
將影像新增至可用作標誌的影像資料夾,然後將影像重新命名為 MyCompanyLogo.jpg。 該影像應該是當設定為 80 像素寬和 20 像素高時您可以清晰看到的影像。
將頁面中的現有內容替換為以下內容:
@{ var imagePath = ""; WebImage WatermarkPhoto = new WebImage(@"~\" + @"\Images\MyCompanyLogo.jpg"); WebImage photo = new WebImage(@"~\Images\Photo4.jpg"); if(photo != null){ imagePath = @"images\Photo4.jpg"; photo.AddImageWatermark(WatermarkPhoto, width: 80, height: 20, horizontalAlign:"Center", verticalAlign:"Bottom", opacity:100, padding:10); photo.Save(@"~\" + imagePath); } } <!DOCTYPE html> <html> <head> <title>Image Watermark</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> </head> <body> <h1>Using an Image as a Watermark</h1> @if(imagePath != ""){ <div class="result"> <img src="@imagePath" alt="Image" /> </div> } </body> </html>
這是早期範例程式碼的另一種變體。 在這種情況下,您可以在儲存影像之前呼叫
AddImageWatermark
將浮水印影像添加到目標影像 (Photo3.jpg)。 當您呼叫AddImageWatermark
時,您將其寬度設為 80 像素,高度設定為 20 像素。 MyCompanyLogo.jpg 影像在目標影像的中心水平對齊,在底部垂直對齊。 不透明度設定為 100%,填滿設定為 10 像素。 如果水印影像比目標影像大,則不會發生任何情況。 如果水印影像大於目標影像,並且將影像浮水印的填滿設為零,則浮水印將被忽略。和以前一樣,您使用
<img>
元素和動態src
屬性來顯示影像。在瀏覽器中執行該頁面。 請注意,水印影像出現在主影像的底部。