I am new to Blazor Webassembly. I am trying to take a simple photo on my Android device (Samsung Galaxy Tab S7 FE).
Here is the code
<div>
<InputFile OnChange="@OnFileSelection" id="ImageInput"></InputFile>
<img src="@imgUrl" style="max-width: 500px; max-height: 500px;">
</div>
@code {
private async Task OnFileSelection(InputFileChangeEventArgs e)
{
IBrowserFile imgFile = e.File;
var currentImageType = imgFile.ContentType;
var resizedImageFile = await imgFile.RequestImageFileAsync(currentImageType, 1000, 1000);
var imageBytes = new byte[resizedImageFile.Size];
await resizedImageFile.OpenReadStream().ReadAsync(imageBytes);
imgUrl = $"data:{currentImageType};base64,{Convert.ToBase64String(imageBytes)}";
StateHasChanged();
}
}
On Windows in Edge, the InputFile works as Upload, because I have no camera installed i guess. On my Android Device I got the Popup (just once) to choose between Camera or Upload (FileExplorer).
So I am choosing Camera, the camera opens and after taking the photo and confirm the photo with "OK", the app crashes and restarts with the Message "Unable to complete previous operation due to low memory".
At first, I tried using await imgFile.OpenReadStream().ReadAsync(CurrentImageBytes); on the original image, without scaling the image down with await imgFile.RequestImageFileAsync(currentImageType, 1000, 1000);.
But in this case, it worked never.
With scaling the image to 1000x1000 it crashes only lets say every 5th time. (but sometimes it still crashes at the first time)
Is there any best practise example for taking images with Blazor Webassemblys or can i make other improvments on the memory usage?
EDIT:
As mentioned, the app does not crash every time, so I am able to take some photos and save them to my DB (I am using SqliteWasmHelper Nuget).
The app does not crash, display more than 10 images at the same time, using the base64 transformation for each of them.
<div style="display: flex; flex-direction: row; gap: 10px; flex-wrap: wrap;">
@foreach (var bitimage in myImages)
{
<img src="@bitimage.ImageByteSource" style="max-width: 200px; max-height: 200px; object-fit:contain;">
}
</div>
public string ImageByteSource
{
get
{
var imagesrc = Convert.ToBase64String(ImageData);
return string.Format("data:image/jpeg;base64,{0}", imagesrc);
}
}
EDIT 2:
Even if I reduce my method to a minimum and just display to a label the size of the image result:
private async Task OnFileSelection(InputFileChangeEventArgs e)
{
IBrowserFile imgFile = e.File;
CurrentImageType = imgFile.ContentType;
ImageBytesLabel = imgFile.Size.ToString();
}
I get the memory error. Is there a way to set the maximum resolution of the taken image BEFORE taking the image.
EDIT 3: I DO NOT crash on my Google Pixel 7, old HUAWEI Tab or on my iPAD. Meanwhile i think, the problem is the build in camera app from Samsung. I had problems with Xamarin.Android an images on this tablet too. The app uses all of the memory (or releases all memory) for the camera app.

Given you must load all bytes into memory in order to convert it to a Base64 string, consider increasing
maxAllowedSizewhich is 500 KB by default.