在 ASP.NET Core Blazor 中使用映像
注意
這不是這篇文章的最新版本。 如需目前版本,請參閱本文的 .NET 8 版本。
本文說明在應用程式中使用映像的 Blazor 常見情節。
動態設定映像來源
下列範例示範如何使用 C# 欄位,動態設定映像的來源。
如需本節中的範例:
從任何來源取得三個映像,或以滑鼠右鍵按一下以下每個映像,以將其儲存在本機。 將映像命名為
image1.png
、image2.png
和image3.png
。將映像放在應用程式 Web 根目錄 (
wwwroot
) 中名為images
的新資料夾中。images
資料夾的使用僅供示範之用。 您能夠以您偏好的任何資料夾配置整理映像,包括直接從wwwroot
資料夾提供映像。
在下列 ShowImage1
元件中:
- 映像的來源 (
src
) 會以動態方式設定為 C# 中imageSource
的值。 ShowImage
方法會根據傳遞至方法的映像id
引數來更新imageSource
欄位。- 轉譯的按鈕會針對
images
資料夾中三個可用的映像,使用映像引數呼叫ShowImage
方法。 檔案名稱是使用傳遞至方法的引數所組成,並符合images
資料夾中三個映像的其中一個。
ShowImage1.razor
:
@page "/show-image-1"
<PageTitle>Show Image 1</PageTitle>
<h1>Show Image Example 1</h1>
@if (imageSource is not null)
{
<p>
<img src="@imageSource" />
</p>
}
@for (var i = 1; i <= 3; i++)
{
var imageId = i;
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
@code {
private string? imageSource;
private void ShowImage(int id)
{
imageSource = $"images/image{id}.png";
}
}
@page "/show-image-1"
<h1>Dynamic Image Source Example</h1>
@if (imageSource is not null)
{
<p>
<img src="@imageSource" />
</p>
}
@for (var i = 1; i <= 3; i++)
{
var imageId = i;
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
@code {
private string? imageSource;
private void ShowImage(int id)
{
imageSource = $"images/image{id}.png";
}
}
@page "/show-image-1"
<h1>Dynamic Image Source Example</h1>
@if (imageSource is not null)
{
<p>
<img src="@imageSource" />
</p>
}
@for (var i = 1; i <= 3; i++)
{
var imageId = i;
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
@code {
private string? imageSource;
private void ShowImage(int id)
{
imageSource = $"images/image{id}.png";
}
}
上述範例使用 C# 欄位來保存映像的來源資料,但您也可以使用 C# 屬性來保存資料。
注意
避免直接在 Lambda 運算式中使用迴圈變數,例如上述 for
迴圈範例中的 i
。 否則,所有 Lambda 運算式都會使用相同的變數,這會導致在所有 Lambda 中使用相同的值。 擷取區域變數中的變數值。 在前述範例中:
- 迴圈變數
i
會指派給imageId
。 imageId
會用於 Lambda 運算式中。
或者,將 foreach
迴圈與 Enumerable.Range 搭配使用,此做法不會因上述問題而受影響:
@foreach (var imageId in Enumerable.Range(1,3))
{
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
如需詳細資訊,請參閱 ASP.NET Core Blazor 事件處理。
對映像資料進行串流
您可以使用 Blazor 的串流 Interop 功能,直接將映像傳送至用戶端,而不是將映像裝載在公用 URL。
本節中的範例會使用 JavaScript (JS) Interop 對映像來源資料進行串流。 下列 setImage
JS 函式會接受映像的 <img>
標籤 id
和資料流。 此功能會執行下列步驟:
- 將提供的串流讀入
ArrayBuffer
。 - 建立
Blob
以包裝ArrayBuffer
。 - 建立物件 URL,作為要顯示之映像的位址。
- 用剛才建立的物件 URL,來更新具有指定
imageElementId
的<img>
元素。 - 若要防止記憶體流失,函式會在元件完成使用映像時,呼叫
revokeObjectURL
以處置物件 URL。
<script>
window.setImage = async (imageElementId, imageStream) => {
const arrayBuffer = await imageStream.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
const image = document.getElementById(imageElementId);
image.onload = () => {
URL.revokeObjectURL(url);
}
image.src = url;
}
</script>
注意
如需 JS 位置的一般指導和我們對於生產應用程式的建議,請參閱 ASP.NET Core 中的 JavaScript 位置Blazor 應用程式。
下列 ShowImage2
元件:
- 插入 System.Net.Http.HttpClient 和 Microsoft.JSInterop.IJSRuntime 的服務。
- 包含
<img>
標籤以顯示映像。 - 具有
GetImageStreamAsync
C# 方法以擷取映像的 Stream。 生產應用程式可能會根據特定使用者動態產生映像,或從儲存體擷取映像。 下列範例會擷取dotnet
GitHub 存放庫的 .NET 虛擬人偶。 - 具有在使用者選取之按鈕上觸發的
SetImageAsync
方法。SetImageAsync
會執行下列步驟:- 從
GetImageStreamAsync
擷取 Stream。 - 將 Stream 包裝在 DotNetStreamReference 中,以允許將映像資料串流至用戶端。
- 叫用
setImage
JavaScript 函式,此函式會接受用戶端上的資料。
- 從
注意
伺服器端應用程式會使用專用 HttpClient 服務來提出要求,因此伺服器端 Blazor 應用程式的開發人員不需要採取任何動作,即可註冊 HttpClient 服務。 從 Blazor 專案範本建立應用程式時,用戶端應用程式會有預設的 HttpClient 服務註冊。 如果用戶端應用程式的 Program
檔案中不存在 HttpClient 服務註冊,請透過新增 builder.Services.AddHttpClient();
來加以提供。 如需詳細資訊,請參閱在 ASP.NET Core 中使用 IHttpClientFactory 發出 HTTP 要求。
ShowImage2.razor
:
@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS
<PageTitle>Show Image 2</PageTitle>
<h1>Show Image Example 2</h1>
<p>
<img id="image" />
</p>
<button @onclick="SetImageAsync">
Set Image
</button>
@code {
private async Task<Stream> GetImageStreamAsync()
{
return await Http.GetStreamAsync(
"https://avatars.githubusercontent.com/u/9141961");
}
private async Task SetImageAsync()
{
var imageStream = await GetImageStreamAsync();
var dotnetImageStream = new DotNetStreamReference(imageStream);
await JS.InvokeVoidAsync("setImage", "image", dotnetImageStream);
}
}
@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS
<h1>Stream Image Data Example</h1>
<p>
<img id="image" />
</p>
<button @onclick="SetImageAsync">
Set Image
</button>
@code {
private async Task<Stream> GetImageStreamAsync()
{
return await Http.GetStreamAsync(
"https://avatars.githubusercontent.com/u/9141961");
}
private async Task SetImageAsync()
{
var imageStream = await GetImageStreamAsync();
var dotnetImageStream = new DotNetStreamReference(imageStream);
await JS.InvokeVoidAsync("setImage", "image", dotnetImageStream);
}
}
@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS
<h1>Stream Image Data Example</h1>
<p>
<img id="image" />
</p>
<button @onclick="SetImageAsync">
Set Image
</button>
@code {
private async Task<Stream> GetImageStreamAsync()
{
return await Http.GetStreamAsync(
"https://avatars.githubusercontent.com/u/9141961");
}
private async Task SetImageAsync()
{
var imageStream = await GetImageStreamAsync();
var dotnetImageStream = new DotNetStreamReference(imageStream);
await JS.InvokeVoidAsync("setImage", "image", dotnetImageStream);
}
}
其他資源
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應