New to Telerik UI for BlazorStart a free 30-day trial

Preview Selected or Uploaded Image

Environment

ProductFileSelect for Blazor,
Upload for Blazor

Description

This KB article answers the following questions:

  • How to immediately display the uploaded image files in the Blazor app?
  • How to render an image preview when using the Blazor FileSelect?
  • How to show the uploaded file as a preview when using the Upload control? I prefer to show a Base64 image without saving the file to the server.
  • How to preview the selected image in the Upload OnSelect event?
  • How to get the raw file content from the Upload component and add it to a memory stream?

Solution

Users can preview images that are uploaded through the Upload component or selected through the FileSelect component.

In Blazor, previewing images is easier when using the FileSelect, but based on your requirements you might choose the Upload over the FileSelect or vice versa.

Using the Upload

  1. Set the Accept, AllowedExtensions, and MaxFileSize parameters of the Upload.
  2. Ensure the Blazor app can handle large uploaded files with a size that matches or exceeds MaxFileSize.
  3. Implement a controller action method to receive the uploaded files. Also see the example on the Upload Events page.
  4. Read the uploaded image(s) in the controller and return an image URL or Base64 data URI for the <img> tag(s) to render. You can choose to provide the original image to the UI or a smaller version for greater efficiency.
  5. Subscribe to the Upload OnSuccess event to detect completed file uploads and obtain the <img> tag's src value. You can also use OnSuccess to detect file removals in the Upload component and remove the respective <img> tags.

You cannot preview the image in the Upload OnSelect event, because this event handler has no access to the file contents.

Preview uploaded images when using the Upload component

RAZOR
@inject NavigationManager NavigationManager

<h2>Upload</h2>

<TelerikUpload Accept="@string.Join(",", ImageFileExtensions)"
               AllowedExtensions="@ImageFileExtensions"
               MaxFileSize="@MaxImageSize"
               SaveUrl="@ToAbsoluteUrl("api/upload/saveimage")"
               RemoveUrl="@ToAbsoluteUrl("api/upload/removeimage")"
               OnSuccess="@OnUploadSuccess">
</TelerikUpload>

<div class="image-preview">
    @foreach (var image in UploadImages)
    {
        <img src="@image.ImageSource" class="k-border-2 k-border-solid k-border-primary" />
    }
</div>

<style>
    .image-preview {
        display: flex;
        gap: 2em;
        flex-wrap: wrap;
        align-items: center;
    }

        .image-preview img {
            max-width: 200px;
            max-height: 200px;
        }
</style>

@code {
    private List<string> ImageFileExtensions { get; set; } = new List<string>() { ".jpg", ".jpeg", ".png", ".gif" };

    private int? MaxImageSize { get; set; } = 8 * 1024 * 1024;

    private List<ImageModel> UploadImages { get; set; } = new();

    private void OnUploadSuccess(UploadSuccessEventArgs args)
    {
        var fileInfo = args.Files.First();
    
        if (args.Operation == UploadOperationType.Upload)
        {
            UploadImages.Add(new ImageModel()
            {
                ImageId = fileInfo.Id,
                ImageSource = args.Request.ResponseText
            });
        }
        else
        {
            UploadImages.RemoveAll(x => x.ImageId == fileInfo.Id);
        }
    }

    private string ToAbsoluteUrl(string url)
    {
        return $"{NavigationManager.BaseUri}{url}";
    }

    public class ImageModel
    {
        public string ImageId { get; set; } = string.Empty;
        public string ImageSource { get; set; } = string.Empty;
    }
}

Using the FileSelect

  1. Set the Accept, AllowedExtensions, and MaxFileSize parameters of the FileSelect.
  2. Increase the SignalR message size to match or exceed MaxFileSize.
  3. Subscribe to the FileSelect OnSelect event.
  4. Read the selected image(s) and create a Base64 data URI for the <img> tag(s) to render.
  5. (optional) Subscribe to the FileSelect OnRemove event to remove the image preview.

Preview selected images when using the FileSelect component

@using System.IO;

<h2>FileSelect</h2>

<TelerikFileSelect Accept="@string.Join(",", ImageFileExtensions)"
                   AllowedExtensions="@ImageFileExtensions"
                   MaxFileSize="@MaxImageSize"
                   OnSelect="@OnFileSelectSelect"
                   OnRemove="@OnFileSelectRemove">
</TelerikFileSelect>

@if (FileSelectImages.Any())
{
    <h2>Image Preview</h2>

    <div class="image-preview">
        @foreach (var image in FileSelectImages)
        {
            <img src="@image.ImageSource" class="k-border-2 k-border-solid k-border-primary" />
        }
    </div>
}

<style>
    .image-preview {
        display: flex;
        gap: 2em;
        flex-wrap: wrap;
        align-items: center;
    }

        .image-preview img {
            max-width: 200px;
            max-height: 200px;
        }
</style>

@code {
    private List<string> ImageFileExtensions { get; set; } = new List<string>() { ".jpg", ".jpeg", ".png", ".gif" };

    private int? MaxImageSize { get; set; } = 8 * 1024 * 1024;

    private List<ImageModel> FileSelectImages { get; set; } = new();

    private async Task OnFileSelectSelect(FileSelectEventArgs args)
    {
        foreach (var file in args.Files)
        {
            if (!file.InvalidExtension && !file.InvalidMaxFileSize)
            {
                var imageBytes = new byte[file.Size];
                await using MemoryStream ms = new MemoryStream(imageBytes);
                await file.Stream.CopyToAsync(ms);

                FileSelectImages.Add(new ImageModel()
                {
                    ImageId = file.Id,
                    ImageSource = $"data:image/{file.Extension};base64,{Convert.ToBase64String(ms.ToArray())}"
                });
            }
        }
    }

    private void OnFileSelectRemove(FileSelectEventArgs args)
    {
        foreach (var file in args.Files)
        {
            FileSelectImages.RemoveAll(x => x.ImageId == file.Id);
        }
    }

    public class ImageModel
    {
        public string ImageId { get; set; } = string.Empty;
        public string ImageSource { get; set; } = string.Empty;
    }
}

See Also