教學課程:使用 Azure AI 視覺在 Azure 儲存體中產生影像中繼資料
在本教學課程中,您將了解如何將 Azure AI 視覺服務整合到 Web 應用程式中,為上傳的影像產生中繼資料。 這適用於數位資產管理 (DAM) 案例,例如,如果公司想要快速產生其所有影像的描述性 標題 或可搜尋關鍵詞。
您將使用 Visual Studio 撰寫 MVC Web 應用程式,以接受使用者上傳的影像,並將映像儲存在 Azure Blob 記憶體中。 您將瞭解如何在 C# 中讀取和寫入 Blob,並使用 Blob 元數據將其他資訊附加至您所建立的 Blob。 然後,您會將使用者上傳的每個影像提交至 Azure AI 視覺 API,以產生標題並在中繼資料搜尋影像。 最後,您可以使用 Visual Studio 將應用程式部署至雲端。
本教學課程會示範如何:
- 使用 Azure 入口網站 建立記憶體帳戶和記憶體容器
- 在 Visual Studio 中建立 Web 應用程式,並將其部署至 Azure
- 使用 Azure AI 視覺 API 從影像中擷取資訊
- 將元數據附加至 Azure 儲存體 影像
- 使用 Azure 儲存體 總管檢查影像元數據
提示
使用 Azure AI 視覺來產生中繼資料一節與影像分析最為相關。 如果您只想查看影像分析如何整合到已建立的應用程式,請跳至該處。
如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶。
必要條件
- 已安裝「ASP.NET 和 Web 開發」和「Azure 開發」工作負載的 Visual Studio 2017 Community 版本 或更高版本。
- 已安裝 Azure 儲存體 Explorer 工具。
建立儲存體帳戶
在本節中,您將使用 Azure 入口網站 來建立記憶體帳戶。 然後,您將建立一組容器:一個用來儲存使用者上傳的影像,另一個用來儲存從上傳影像產生的影像縮圖。
在網頁瀏覽器中,登入 Azure 入口網站。 如果系統要求您登入,請使用您的 Microsoft 帳戶進行登入。
若要建立儲存體帳戶,請選取左側功能區中的 [+ 建立資源]。 選取 [儲存體],接著按一下 [儲存體帳戶]。
在 [ 名稱 ] 字段中輸入記憶體帳戶的唯一名稱,並確定旁邊會出現綠色複選標記。 此名稱很重要,因為它會形成URL的一部分,透過此URL來存取在此帳戶下建立的 Blob。 將記憶體帳戶放在名為 「IntellipixResources」 的新資源群組中,然後選取最接近您的區域。 最後選取畫面底端的 [檢閱 + 建立] 按鈕,以建立新的儲存體帳戶。
注意
儲存體 帳戶名稱長度可以是 3 到 24 個字元,而且只能包含數位和小寫字母。 此外,您輸入的名稱在 Azure 內必須是唯一的。 如果其他人已選擇相同的名稱,系統會在 [名稱] 字段中收到名稱無法使用紅色驚嘆號的通知。
選取左側功能區中的 [資源群組]。 然後選取 "IntellipixResources" 資源群組。
在針對資源群組開啟的索引標籤上,選取您已建立的儲存體帳戶。 如果儲存體帳戶尚未在那裡,您可以選取索引標籤頂端的 [重新整理],直到其出現為止。
在儲存體帳戶的索引標籤中,選取 [Blob],以檢視與此帳戶相關聯的容器清單。
記憶體帳戶目前沒有容器。 您必須先建立容器來儲存 Blob,才能建立 Blob。 選取 [+ 容器] 以建立新的容器。 在 [名稱] 字段中輸入
photos
,然後選取 [Blob] 作為 [公用存取層級]。 然後選取 [確定],建立名為「相片」的容器。根據預設,容器及其內容是私人的。 選取 Blob 作為存取層級可公開存取「相片」容器中的 Blob,但不會讓容器本身成為公用。 這是您想要的,因為儲存在「相片」容器中的影像會從 Web 應用程式連結至 。
重複上一個步驟以建立名為「縮圖」的容器,再次確保容器的 公用存取層級 設定為 Blob。
確認這兩個容器都出現在此記憶體帳戶的容器清單中,且名稱拼字正確。
關閉 [Blob 服務] 畫面。 選取儲存體帳戶畫面左側功能表中的 [存取金鑰],然後為 [key1] 選取 [KEY] 旁邊的 [複製] 按鈕。 將此存取鍵貼到您慣用的文字編輯器中,以供稍後使用。
您現在已建立記憶體帳戶,以保存上傳至您要建置之應用程式的映像,以及用來儲存映像的容器。
執行 Azure 儲存體 總管
Azure 儲存體 總管是免費的工具,提供圖形化介面,可在執行 Windows、macOS 和 Linux 的電腦上使用 Azure 儲存體。 它提供與 Azure 入口網站 相同的大部分功能,並提供其他功能,例如檢視 Blob 元數據的功能。 在本節中,您將使用 Microsoft Azure 儲存體總管 來檢視您在上一節中建立的容器。
如果您尚未安裝 儲存體總管,或想要確定您執行的是最新版本,請移至 http://storageexplorer.com/ 並下載並安裝。
開始 儲存體總管。 如果系統要求您登入,請使用您的 Microsoft 帳戶來執行此動作,也就是您用來登入 Azure 入口網站 的帳戶。 如果您在儲存體總管的左窗格中看不到儲存體帳戶,請選取下方反白顯示的 [管理帳戶] 按鈕,並確定您的 Microsoft 帳戶和用來建立儲存體帳戶的訂用帳戶都已新增至儲存體總管。
選取儲存體帳戶旁的小箭號以顯示其內容,然後選取 [Blob 容器] 旁邊的箭號。 確認您建立的容器會出現在清單中。
容器目前是空的,但一旦部署應用程式並開始上傳相片,就會變更。 安裝 儲存體總管 可讓您輕鬆查看應用程式寫入 Blob 記憶體的內容。
在 Visual Studio 中建立新的 Web 應用程式
在本節中,您將在 Visual Studio 中建立新的 Web 應用程式,並新增程式代碼以實作上傳影像、將影像寫入 Blob 記憶體,並將其顯示在網頁中所需的基本功能。
啟動 Visual Studio 並使用 [檔案 -> 新增 -> 專案 ] 命令來建立名為 “Intellipix” 的新 Visual C# ASP.NET Web 應用程式 專案(簡稱 「智能圖片」)。
在 [新增 ASP.NET Web 應用程式] 對話框中,確定 已選取 MVC 。 然後選取確定。
花點時間檢閱 方案總管 中的項目結構。 除此之外,還有一個名為 Controllers 的資料夾 會保存專案的 MVC 控制器 ,還有一 個名為 Views 的資料夾可儲存項目的檢視。 當您實作應用程式時,您將使用這些資料夾和其他資料夾中的資產。
使用 Visual Studio 的 [ 偵錯 -> 啟動但不 偵錯] 命令 (或按 Ctrl+F5) 在瀏覽器中啟動應用程式。 以下是應用程式在目前狀態中的外觀:
關閉瀏覽器並返回 Visual Studio。 在 [方案總管] 中,以滑鼠右鍵按一下 [Intellipix] 專案,然後選取 [管理 NuGet 套件...]。選取 [瀏覽]。 然後在搜尋方塊中輸入
imageresizer
,然後選取名為 ImageResizer 的 NuGet 套件。 最後,選取 [安裝] 以安裝最新穩定的套件版本。 ImageResizer 包含 API,您將用來從上傳至應用程式的影像建立影像縮圖。 確定任何變更,並接受提供給您的任何授權。重複此程式,將名為 WindowsAzure.儲存體 的 NuGet 套件新增至專案。 此套件包含從 .NET 應用程式存取 Azure 儲存體 的 API。 確定任何變更,並接受提供給您的任何授權。
開啟 Web.config 並將下列語句新增至
<appSettings>
區段,並以您在第一個區段中建立的記憶體帳戶名稱取代 ACCOUNT_NAME,並以您儲存的存取金鑰ACCOUNT_KEY。<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=ACCOUNT_NAME;AccountKey=ACCOUNT_KEY" />
重要
Web.config 檔案的目的是保存訂用帳戶金鑰等機密資訊,而具有 .config 副檔名的檔案的任何 HTTP 要求都是由 ASP.NET 引擎處理,這會傳回「未提供此類型的頁面」訊息。 不過,如果攻擊者能找到其他惡意探索,讓他們檢視 Web.config 內容,他們就能公開該資訊。 如需進一步保護 Web.config 資料所需的額外步驟,請參閱保護連接字串和其他設定資訊。
在專案的 Views/Shared 資料夾中開啟名為 _Layout.cshtml 的檔案。 在行 19 上,將 [應用程式名稱] 變更為 “Intellipix”。這一行看起來應該像這樣:
@Html.ActionLink("Intellipix", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
注意
在 ASP.NET MVC 專案中, _Layout.cshtml 是特殊檢視,可作為其他檢視的範本。 您通常會定義此檔案中所有檢視通用的頁首和頁尾內容。
以滑鼠右鍵按兩下專案的 Models 資料夾,並使用 Add -> Class... 命令,將名為 BlobInfo.cs 的類別檔案新增至資料夾。 然後將空 的 BlobInfo 類別取代為下列類別定義:
public class BlobInfo { public string ImageUri { get; set; } public string ThumbnailUri { get; set; } public string Caption { get; set; } }
從專案的 Controllers 資料夾開啟HomeController.cs,並將下列
using
語句新增至檔案頂端:using ImageResizer; using Intellipix.Models; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob; using System.Configuration; using System.Threading.Tasks; using System.IO;
將 HomeController.cs 中的 Index 方法取代為下列實作:
public ActionResult Index() { // Pass a list of blob URIs in ViewBag CloudStorageAccount account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]); CloudBlobClient client = account.CreateCloudBlobClient(); CloudBlobContainer container = client.GetContainerReference("photos"); List<BlobInfo> blobs = new List<BlobInfo>(); foreach (IListBlobItem item in container.ListBlobs()) { var blob = item as CloudBlockBlob; if (blob != null) { blobs.Add(new BlobInfo() { ImageUri = blob.Uri.ToString(), ThumbnailUri = blob.Uri.ToString().Replace("/photos/", "/thumbnails/") }); } } ViewBag.Blobs = blobs.ToArray(); return View(); }
新的 Index 方法會列舉容器中的
"photos"
Blob,並透過 ASP.NET MVC 的 ViewBag 屬性,將代表這些 Blob 的 Blob 數位傳遞至檢視。 稍後,您將修改檢視來列舉這些物件,並顯示相片縮圖的集合。 您將用來存取記憶體帳戶並列舉 Blob-Cloud 儲存體 Account、CloudBlobClient 和 CloudBlobContainer 等類別,來自您透過 NuGet 安裝的 WindowsAzure.儲存體 套件。將下列方法新增至 HomeController.cs 中的 HomeController 類別:
[HttpPost] public async Task<ActionResult> Upload(HttpPostedFileBase file) { if (file != null && file.ContentLength > 0) { // Make sure the user selected an image file if (!file.ContentType.StartsWith("image")) { TempData["Message"] = "Only image files may be uploaded"; } else { try { // Save the original image in the "photos" container CloudStorageAccount account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]); CloudBlobClient client = account.CreateCloudBlobClient(); CloudBlobContainer container = client.GetContainerReference("photos"); CloudBlockBlob photo = container.GetBlockBlobReference(Path.GetFileName(file.FileName)); await photo.UploadFromStreamAsync(file.InputStream); // Generate a thumbnail and save it in the "thumbnails" container using (var outputStream = new MemoryStream()) { file.InputStream.Seek(0L, SeekOrigin.Begin); var settings = new ResizeSettings { MaxWidth = 192 }; ImageBuilder.Current.Build(file.InputStream, outputStream, settings); outputStream.Seek(0L, SeekOrigin.Begin); container = client.GetContainerReference("thumbnails"); CloudBlockBlob thumbnail = container.GetBlockBlobReference(Path.GetFileName(file.FileName)); await thumbnail.UploadFromStreamAsync(outputStream); } } catch (Exception ex) { // In case something goes wrong TempData["Message"] = ex.Message; } } } return RedirectToAction("Index"); }
這是上傳相片時所呼叫的方法。 它會將每個上傳的影像儲存為容器中的
"photos"
Blob、使用ImageResizer
封裝從原始映像建立縮圖影像,並將縮圖影像儲存為容器中的"thumbnails"
Blob。在專案的 Views/Home 資料夾中開啟 Index.cshmtl,並以下列程式代碼和標記取代其內容:
@{ ViewBag.Title = "Intellipix Home Page"; } @using Intellipix.Models <div class="container" style="padding-top: 24px"> <div class="row"> <div class="col-sm-8"> @using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { <input type="file" name="file" id="upload" style="display: none" onchange="$('#submit').click();" /> <input type="button" value="Upload a Photo" class="btn btn-primary btn-lg" onclick="$('#upload').click();" /> <input type="submit" id="submit" style="display: none" /> } </div> <div class="col-sm-4 pull-right"> </div> </div> <hr /> <div class="row"> <div class="col-sm-12"> @foreach (BlobInfo blob in ViewBag.Blobs) { <img src="@blob.ThumbnailUri" width="192" title="@blob.Caption" style="padding-right: 16px; padding-bottom: 16px" /> } </div> </div> </div> @section scripts { <script type="text/javascript" language="javascript"> if ("@TempData["Message"]" !== "") { alert("@TempData["Message"]"); } </script> }
這裡使用的語言是 Razor,可讓您在 HTML 標記中內嵌可執行的程式代碼。 檔案
@foreach
中間的 語句會列舉從 ViewBag 中控制器傳遞的 BlobInfo 物件,並從中建立 HTML<img>
元素。src
每個元素的 屬性都會使用包含影像縮圖之 Blob 的 URI 初始化。從 GitHub 範例數據存放庫下載並解壓縮photos.zip檔案。 這是一系列可用來測試應用程式的不同相片。
儲存您的變更,然後按 Ctrl+F5 以在瀏覽器中啟動應用程式。 然後選取 [上傳相片],並上傳您已下載的其中一個影像。 確認相片的縮圖版本會出現在頁面上。
從您的 相片 資料夾上傳更多影像。 確認它們也會出現在頁面上:
在瀏覽器中按下滑鼠右鍵,然後選取 [檢視頁面來源 ] 以檢視頁面的原始程式碼。
<img>
尋找代表影像縮圖的專案。 觀察指派給映像的 URL 會直接參考 Blob 記憶體中的 Blob。 這是因為您將容器的 公用存取層級 設定為 Blob,讓 Blob 在可公開存取內。返回 [Azure 儲存體 總管],或在記憶體帳戶下選取
"photos"
容器,然後重新啟動它。 容器中的 Blob 數目應等於您上傳的相片數目。 按兩下其中一個 Blob 來下載它,並查看儲存在 Blob 中的映像。在
"thumbnails"
儲存體總管 中開啟容器。 開啟其中一個 Blob,以檢視從影像上傳產生的縮圖影像。
應用程式尚未提供一種方式來檢視您上傳的原始影像。 在理想情況下,選取影像縮圖應該會顯示原始影像。 接下來,您將新增該功能。
新增用於檢視相片的燈箱
在本節中,您將使用免費的開放原始碼 JavaScript 連結庫來新增 Lightbox 查看器,讓使用者能夠查看他們上傳的原始影像(而非影像縮圖)。 系統會為您提供這些檔案。 您只需要將它們整合到專案中,並稍微修改 Index.cshtml。
從 GitHub 程式代碼存放庫下載lightbox.css和lightbox.js檔案。
在 方案總管 中,以滑鼠右鍵按兩下專案的 Scripts 資料夾,並使用[新增-> 新增專案...] 命令來建立lightbox.js檔案。 貼上 GitHub 程式代碼存放庫中範例檔案的內容。
以滑鼠右鍵按兩下專案的 [內容] 資料夾,然後使用 [新增 -> 新增專案... ] 命令來建立 lightbox.css 檔案。 貼上 GitHub 程式代碼存放庫中範例檔案的內容。
從 GitHub 資料檔存放庫下載並解壓縮 buttons.zip 檔案: https://github.com/Azure-Samples/cognitive-services-sample-data-files/tree/master/ComputerVision/storage-lab-tutorial。 您應該有四個按鈕影像。
以滑鼠右鍵按兩下 方案總管中的 Intellipix 專案,並使用 [新增 -> 新增資料夾] 命令,將名為 “Images” 的資料夾新增至專案。
以滑鼠右鍵按兩下 Images 資料夾,並使用 [新增 -> 現有專案... ] 命令匯入您下載的四個影像。
在專案的 「App_Start」 資料夾中開啟 BundleConfig.cs 。 將下列語句新增至
RegisterBundles
BundleConfig.cs 中的 方法:bundles.Add(new ScriptBundle("~/bundles/lightbox").Include( "~/Scripts/lightbox.js"));
在相同的方法中,尋找從 “~/Content/css” 建立
StyleBundle
的 語句,並將lightbox.css新增至套件組合中的樣式表單清單。 以下是修改過的語句:bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/bootstrap.css", "~/Content/site.css", "~/Content/lightbox.css"));
在專案的 Views/Shared 資料夾中開啟 _Layout.cshtml,並在靠近底部的 語句之前
@RenderSection
新增下列語句:@Scripts.Render("~/bundles/lightbox")
最後一項工作是將 lightbox 查看器併入首頁。 若要這樣做,請開啟 Index.cshtml (它位於專案的 Views/Home 資料夾中),並將 迴圈取代
@foreach
為下列迴圈:@foreach (BlobInfo blob in ViewBag.Blobs) { <a href="@blob.ImageUri" rel="lightbox" title="@blob.Caption"> <img src="@blob.ThumbnailUri" width="192" title="@blob.Caption" style="padding-right: 16px; padding-bottom: 16px" /> </a> }
儲存您的變更,然後按 Ctrl+F5 以在瀏覽器中啟動應用程式。 然後選取您先前上傳的其中一個影像。 確認燈箱隨即出現,並顯示影像的放大檢視。
選取 Lightbox 右下角的 X 來將其關閉。
現在您可以檢視已上傳的影像。 下一個步驟是使用這些映像執行更多動作。
使用 Azure AI 視覺來產生中繼資料
建立視覺資源
您必須為 Azure 帳戶建立 電腦視覺 資源;此資源會管理您對 Azure 的 Azure AI 視覺服務的存取權。
請遵循建立 Azure AI 服務資源中的指示來建立多服務資源或視覺資源。
然後移至資源群組的功能表,選取您建立的視覺資源。 將 [端點] 底下的 URL 複製到您可以輕鬆地在某個位置擷取它。 然後選取 [ 顯示存取金鑰]。
注意
在 2019 年 7 月 1 日之後建立的新資源將會使用自定義子域名稱。 如需詳細資訊和完整的區域端點清單,請參閱 Azure AI 服務的自訂子網域名稱。
在下一個視窗中,將 KEY 1 的值複製到剪貼簿。
新增 Azure AI 視覺認證
接著,您會將必要的認證新增至您的應用程式,使其可存取視覺資源。
流覽至 專案根目錄的 Web.config 檔案。 將下列語句新增至 <appSettings>
檔案的 區段,並將 取代為您在上一個步驟中複製的金鑰,並以VISION_ENDPOINT
您在先前步驟中儲存的 URL 取代 VISION_KEY
。
<add key="SubscriptionKey" value="VISION_KEY" />
<add key="VisionEndpoint" value="VISION_ENDPOINT" />
在 方案總管 中。 以滑鼠右鍵按兩下專案方案,然後選取 [ 管理 NuGet 套件]。 在開啟的套件管理員中,選取 [流覽],勾選 [包含發行前版本],然後搜尋 Azure.AI.Vision.ImageAnalysis。 選取安裝。
新增元數據產生程序代碼
接著,您會新增實際使用 Azure AI 視覺服務來建立影像中繼資料的程式碼。
在專案的 Controllers 資料夾中開啟HomeController.cs檔案,並在檔案頂端新增下列
using
語句:using Azure; using Azure.AI.Vision.ImageAnalysis; using System;
然後,移至 Upload 方法;這個方法會將影像轉換為 Blob 記憶體。 在開頭
// Generate a thumbnail
為 的區塊後面立即新增下列程式代碼(或在 image-blob-creation 程序結束時)。 此程式碼會取用包含影像的 Blob (photo
),並使用 Azure AI 視覺產生該影像的描述。 Azure AI 視覺 API 也會產生套用至影像的關鍵字清單。 產生的描述和關鍵詞會儲存在 Blob 的元數據中,以便稍後擷取它們。// create a new ImageAnalysisClient ImageAnalysisClient client = new ImageAnalysisClient( new Uri(Environment.GetEnvironmentVariable(ConfigurationManager.AppSettings["VisionEndpoint"])), new AzureKeyCredential(ConfigurationManager.AppSettings["SubscriptionKey"])); VisualFeatures = visualFeatures = VisualFeatures.Caption | VisualFeatures.Tags; ImageAnalysisOptions analysisOptions = new ImageAnalysisOptions() { GenderNeutralCaption = true, Language = "en", }; Uri imageURL = new Uri(photo.Uri.ToString()); ImageAnalysisResult result = client.Analyze(imageURL,visualFeatures,analysisOptions); // Record the image description and tags in blob metadata photo.Metadata.Add("Caption", result.Caption.Text); for (int i = 0; i < result.Tags.Values.Count; i++) { string key = String.Format("Tag{0}", i); photo.Metadata.Add(key, result.Tags.Values[i]); } await photo.SetMetadataAsync();
接下來,移至 相同檔案中的 Index 方法。 這個方法會列舉目標 Blob 容器中儲存的映像 Blob(如 IListBlobItem 實例),並將其傳遞至應用程式檢視。
foreach
以下列程式代碼取代此方法中的 區塊。 此程式代碼會呼叫 CloudBlockBlob.FetchAttributes 來取得每個 Blob 的附加元數據。 它會從元數據擷取計算機產生的描述 (caption
),並將它新增至 BlobInfo 物件,該物件會傳遞至檢視。foreach (IListBlobItem item in container.ListBlobs()) { var blob = item as CloudBlockBlob; if (blob != null) { blob.FetchAttributes(); // Get blob metadata var caption = blob.Metadata.ContainsKey("Caption") ? blob.Metadata["Caption"] : blob.Name; blobs.Add(new BlobInfo() { ImageUri = blob.Uri.ToString(), ThumbnailUri = blob.Uri.ToString().Replace("/photos/", "/thumbnails/"), Caption = caption }); } }
測試應用程式
將變更儲存在 Visual Studio 中,然後按 Ctrl+F5 以在瀏覽器中啟動應用程式。 使用應用程式,從您下載的相片集或從您自己的資料夾上傳更多影像。 當您將游標停留在檢視中的其中一個新影像上時,工具提示視窗應該會出現並顯示計算機產生的影像 標題。
若要檢視所有附加的元數據,請使用 Azure 儲存體 Explorer 來檢視您用於映像的記憶體容器。 以滑鼠右鍵按兩下容器中的任何 Blob,然後選取 [ 屬性]。 在對話框中,您會看到索引鍵/值組的清單。 計算機產生的影像描述會儲存在專案中 Caption
,而搜尋關鍵詞會儲存在 Tag0
、 Tag1
等等。 完成作業後,請選取 [取消] 以關閉對話方塊。
將搜尋新增至應用程式
在本節中,您會將搜尋方塊新增至首頁,讓使用者在已上傳的影像上執行關鍵詞搜尋。 關鍵字是 Azure AI 視覺 API 所產生並儲存在 Blob 中繼資料中的關鍵字。
在專案的 Views/Home 資料夾中開啟 Index.cshtml,並使用 屬性將下列語句新增至空白
<div>
元素class="col-sm-4 pull-right"
:@using (Html.BeginForm("Search", "Home", FormMethod.Post, new { enctype = "multipart/form-data", @class = "navbar-form" })) { <div class="input-group"> <input type="text" class="form-control" placeholder="Search photos" name="term" value="@ViewBag.Search" style="max-width: 800px"> <span class="input-group-btn"> <button class="btn btn-primary" type="submit"> <i class="glyphicon glyphicon-search"></i> </button> </span> </div> }
此程式代碼和標記會將搜尋方塊和 [搜尋 ] 按鈕新增至首頁。
在專案的 Controllers 資料夾中開啟HomeController.cs,並將下列方法新增至 HomeController 類別:
[HttpPost] public ActionResult Search(string term) { return RedirectToAction("Index", new { id = term }); }
這是當使用者選取前一個步驟中所新增的 [搜尋] 按鈕時所呼叫的方法。 它會重新整理頁面,並在 URL 中包含搜尋參數。
以 下列實作取代 Index 方法:
public ActionResult Index(string id) { // Pass a list of blob URIs and captions in ViewBag CloudStorageAccount account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]); CloudBlobClient client = account.CreateCloudBlobClient(); CloudBlobContainer container = client.GetContainerReference("photos"); List<BlobInfo> blobs = new List<BlobInfo>(); foreach (IListBlobItem item in container.ListBlobs()) { var blob = item as CloudBlockBlob; if (blob != null) { blob.FetchAttributes(); // Get blob metadata if (String.IsNullOrEmpty(id) || HasMatchingMetadata(blob, id)) { var caption = blob.Metadata.ContainsKey("Caption") ? blob.Metadata["Caption"] : blob.Name; blobs.Add(new BlobInfo() { ImageUri = blob.Uri.ToString(), ThumbnailUri = blob.Uri.ToString().Replace("/photos/", "/thumbnails/"), Caption = caption }); } } } ViewBag.Blobs = blobs.ToArray(); ViewBag.Search = id; // Prevent search box from losing its content return View(); }
觀察 Index 方法現在接受參數
id
,其中包含使用者在搜尋方塊中輸入的值。 空白或遺漏id
的參數表示應該顯示所有相片。將下列協助程式方法新增至 HomeController 類別:
private bool HasMatchingMetadata(CloudBlockBlob blob, string term) { foreach (var item in blob.Metadata) { if (item.Key.StartsWith("Tag") && item.Value.Equals(term, StringComparison.InvariantCultureIgnoreCase)) return true; } return false; }
Index 方法會呼叫這個方法,以判斷附加至指定影像 Blob 的元數據關鍵詞是否包含使用者輸入的搜尋字詞。
再次啟動應用程式並上傳數張相片。 您可以隨意使用自己的相片,而不只是教學課程所提供的相片。
在搜尋方塊中輸入關鍵詞,例如 「river」。。 然後選取 [搜尋] 按鈕。
搜尋結果會根據您輸入的內容和您上傳的影像而有所不同。 但結果應該是已篩選的影像清單,其元數據關鍵詞包含您輸入之關鍵詞的所有或部分。
選取瀏覽器的上一頁按鈕,來重新顯示所有影像。
您只剩下最後一步。 是時候將應用程式部署至雲端了。
將應用程式部署至 Azure
在本節中,您會從 Visual Studio 將應用程式部署至 Azure。 您將允許 Visual Studio 為您建立 Azure Web 應用程式,讓您不必進入 Azure 入口網站 並個別建立。
以滑鼠右鍵按兩下 方案總管中的項目,然後從操作功能表中選取 [發佈...]。 確定已選取 Microsoft Azure App Service 和 [建立新項目],然後選取 [發佈] 按鈕。
在下一個對話框中,選取 [資源群組] 底下的 [IntellipixResources] 資源群組。 選取 [App Service 方案] 旁邊的 [新增...] 按鈕,並在 [建立儲存體帳戶] 中為儲存體帳戶選取的同一位置中建立新的 App Service 方案,同時接受其他任何地方的預設值。 選取 [建立] 按鈕來完成。
幾分鐘后,應用程式會出現在瀏覽器視窗中。 記下網址列中的URL。 應用程式不再在本機執行;它位於網路上,可公開接觸。
如果您對應用程式進行變更,並想要將變更推送至 Web,請再次執行發佈程式。 您仍然可以在本機測試變更,再發佈至 Web。
清除資源
如果您想要繼續處理 Web 應用程式,請參閱 後續步驟 一節。 如果您不打算繼續使用此應用程式,您應該刪除所有應用程式特定的資源。 若要刪除資源,您可以刪除包含 Azure 儲存體訂用帳戶和視覺資源的資源群組。 這會移除記憶體帳戶、上傳至它的 Blob,以及與 ASP.NET Web 應用程式連線所需的 App Service 資源。
若要刪除資源群組,請在入口網站中開啟 [資源群組] 索引標籤,並瀏覽至您用於此專案的資源群組,然後選取檢視頂端的 [刪除資源群組]。 系統會要求您輸入資源組名,以確認您想要將其刪除。 刪除之後,就無法復原資源群組。
下一步
您可以執行更多動作來使用 Azure 並進一步開發 Intellipix 應用程式。 例如,您可以新增驗證使用者和刪除相片的支援,而不是強制使用者等候 Azure AI 服務在上傳之後處理相片,您可以使用 Azure Functions,在每次將影像新增至 Blob 儲存體時,以非同步方式呼叫 Azure AI 視覺 API。 您也可以在影像上執行任意數目的其他影像分析作業,如概觀中所述。