Udostępnij za pośrednictwem


Praca z obrazami w programie ASP.NET Core Blazor

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

W tym artykule opisano typowe scenariusze pracy z obrazami w Blazor aplikacjach.

Dynamiczne ustawianie źródła obrazu

W poniższym przykładzie pokazano, jak dynamicznie ustawić źródło obrazu przy użyciu pola języka C#.

Przykład w tej sekcji:

  • Uzyskaj trzy obrazy z dowolnego źródła lub kliknij prawym przyciskiem myszy każdy z poniższych obrazów, aby zapisać je lokalnie. Nazwij obrazy image1.png, image2.pngi image3.png.

    Ikona komputeraIkona buźkiIkona Ziemi

  • Umieść obrazy w nowym folderze o nazwie images w katalogu głównym aplikacji (wwwroot). Korzystanie z images folderu jest przeznaczone tylko do celów demonstracyjnych. Obrazy można organizować w dowolnym preferowanym układzie folderów, w tym obsługiwać obrazy bezpośrednio z wwwroot folderu.

W poniższym składniku ShowImage1:

  • Źródło obrazu (src) jest dynamicznie ustawiane na wartość imageSource w języku C#.
  • Metoda ShowImage aktualizuje imageSource pole na podstawie argumentu obrazu id przekazanego do metody .
  • Przyciski renderowane powodują wywołanie ShowImage metody z argumentem obrazu dla każdego z trzech dostępnych obrazów w folderze images . Nazwa pliku składa się przy użyciu argumentu przekazanego do metody i pasuje do jednego z trzech obrazów w folderze 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";
    }
}

W poprzednim przykładzie do przechowywania danych źródłowych obrazu jest używane pole języka C#, ale do przechowywania danych można również użyć właściwości języka C#.

Uwaga

Unikaj używania zmiennej pętli bezpośrednio w wyrażeniu lambda, takim jak i w poprzednim przykładzie for pętli. W przeciwnym razie ta sama zmienna jest używana przez wszystkie wyrażenia lambda, co powoduje użycie tej samej wartości we wszystkich wyrażeniach lambda. Przechwyć wartość zmiennej w zmiennej lokalnej. W powyższym przykładzie:

  • Zmienna pętli jest przypisywana do imageIdzmiennej i .
  • imageId jest używany w wyrażeniu lambda.

Alternatywnie należy użyć foreach pętli z elementem Enumerable.Range, która nie ma problemu z poprzednim:

@foreach (var imageId in Enumerable.Range(1,3))
{
    <button @onclick="() => ShowImage(imageId)">
        Image @imageId
    </button>
}

Aby uzyskać więcej informacji, zobacz obsługa zdarzeń ASP.NET CoreBlazor.

Przesyłanie strumieniowe danych obrazów

Obraz można wysyłać bezpośrednio do klienta przy użyciu Blazorfunkcji międzyoperacjności przesyłania strumieniowego zamiast hostowania obrazu pod publicznym adresem URL.

Przykład w tej sekcji przesyła strumieniowo dane źródła obrazów przy użyciu międzyoperacyjności języka JavaScript (JS). Poniższa setImageJS funkcja akceptuje <img> tag id i strumień danych dla obrazu. Funkcja wykonuje następujące czynności:

  • Odczytuje udostępniony strumień do elementu ArrayBuffer.
  • Tworzy obiekt w Blob celu opakowania .ArrayBuffer
  • Tworzy adres URL obiektu, który będzie służył jako adres obrazu, który ma być wyświetlany.
  • <img> Aktualizacje element z określonym imageElementId adresem URL obiektu, który właśnie został utworzony.
  • Aby zapobiec wyciekom pamięci, funkcja wywołuje revokeObjectURL metodę usuwania adresu URL obiektu po zakończeniu pracy składnika z obrazem.
<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>

Uwaga

Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.

ShowImage2 Następujący składnik:

  • Wprowadza usługi dla elementu System.Net.Http.HttpClient i Microsoft.JSInterop.IJSRuntime.
  • <img> Zawiera tag do wyświetlenia obrazu.
  • Ma metodę GetImageStreamAsync języka C#, aby pobrać Stream element dla obrazu. Aplikacja produkcyjna może dynamicznie generować obraz na podstawie określonego użytkownika lub pobierać obraz z magazynu. Poniższy przykład pobiera awatar platformy .NET dla dotnet repozytorium GitHub.
  • Ma metodę SetImageAsync wyzwalaną przez użytkownika po wybraniu przycisku. SetImageAsync wykonuje następujące kroki:
    • Pobiera element Stream z GetImageStreamAsync.
    • Opakowuje element Stream w obiekcie DotNetStreamReference, który umożliwia przesyłanie strumieniowe danych obrazu do klienta.
    • setImage Wywołuje funkcję JavaScript, która akceptuje dane na kliencie.

Uwaga

Aplikacje po stronie serwera używają dedykowanej HttpClient usługi do tworzenia żądań, więc deweloper aplikacji po stronie Blazor serwera nie musi wykonywać żadnych działań w celu zarejestrowania HttpClient usługi. Aplikacje po stronie klienta mają domyślną HttpClient rejestrację usługi podczas tworzenia aplikacji na podstawie Blazor szablonu projektu. HttpClient Jeśli rejestracja usługi nie istnieje w Program pliku aplikacji po stronie klienta, podaj je, dodając element builder.Services.AddHttpClient();. Aby uzyskać więcej informacji, zobacz Tworzenie żądań HTTP za pomocą interfejsu IHttpClientFactory na platformie ASP.NET Core.

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);
    }
}

Dodatkowe zasoby