PROWAREtech
Blazor: Resize and Upload Image Files
This example uses .NET 6. It is compatible with .NET 5 and .NET 8 but incompatible with earlier versions of .NET including .NET Core 3.1.
This is an example of using the InputFile
of .NET 6.
This example involves turning the files into base64 strings to be uploaded via JSON to the server. It resizes images on the client-side, utilizing client resources thereby freeing server resources.
This example uploads image files, but it can be used to upload any kind of file. See this article for further examples.
Create a new .NET 5 (or later) Blazor WebAssembly project with an ASP.NET Core backend.
Add New File Class to Project
In the root of the shared project, create a file named ImageFile.cs.
// ImageFile.cs
public class ImageFile
{
public string base64data { get; set; }
public string contentType { get; set; }
public string fileName { get; set; }
}
Create the Upload Controller
In the root of the server project, create a file named UploadController.cs.
// UploadController.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System;
using Microsoft.AspNetCore.Hosting;
namespace BlazorApp1.Server.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class UploadController : ControllerBase
{
private readonly IWebHostEnvironment env;
public UploadController(IWebHostEnvironment env)
{
this.env = env;
}
[HttpPost]
public async Task Post([FromBody] ImageFile[] files)
{
foreach (var file in files)
{
var buf = Convert.FromBase64String(file.base64data);
await System.IO.File.WriteAllBytesAsync(env.ContentRootPath + System.IO.Path.DirectorySeparatorChar + Guid.NewGuid().ToString("N") + "-" + file.fileName, buf);
}
}
}
}
Modify Index.razor
In the client project, modify Index.razor.
@page "/"
@inject HttpClient Http
<h1>@message</h1>
<div class="input-group">
<div class="custom-file">
<InputFile class="custom-file-input" multiple OnChange="OnChange" accept="image/png, image/jpeg, image/gif" id="inputFile" />
<label class="custom-file-label" for="inputFile">Choose file</label>
</div>
<div class="input-group-append">
<button class="btn btn-success" @onclick="Upload" disabled="@isDisabled">Upload</button>
</div>
</div>
@foreach (var item in filesBase64)
{
<img src="data:@item.contentType;base64,@item.base64data" />
}
@code {
List<ImageFile> filesBase64 = new List<ImageFile>();
string message = "InputFile";
bool isDisabled = false;
async Task OnChange(InputFileChangeEventArgs e)
{
var files = e.GetMultipleFiles(); // get the files selected by the users
foreach(var file in files)
{
var resizedFile = await file.RequestImageFileAsync(file.ContentType, 640, 480); // resize the image file
var buf = new byte[resizedFile.Size]; // allocate a buffer to fill with the file's data
using (var stream = resizedFile.OpenReadStream())
{
await stream.ReadAsync(buf); // copy the stream to the buffer
}
filesBase64.Add(new ImageFile { base64data = Convert.ToBase64String(buf), contentType = file.ContentType, fileName = file.Name }); // convert to a base64 string!!
}
message = "Click UPLOAD to continue";
}
async Task Upload()
{
isDisabled = true;
using (var msg = await Http.PostAsJsonAsync<List<ImageFile>>("/api/upload", filesBase64, System.Threading.CancellationToken.None))
{
isDisabled = false;
if (msg.IsSuccessStatusCode)
{
message = $"{filesBase64.Count} files uploaded";
filesBase64.Clear();
}
}
}
}
Try the Home Page of The Project
Run the application to preview and then upload images to the server where they are saved in the server's content directory.