I am trying to upload multiple images from a Blazor InputFile component:
<InputFile OnChange="@LoadFiles" multiple accept=".png, .jpg, .jpeg, .gif" />
Once in memory, using SkiaSharp I need to resize them down to a maximum of 1000 pixels wide/high. I created a helper method for this, but it seems to fail on any image that is over approximately 4MB. I have pieced the following logic together from searches plus whatever (rather lacking) Microsoft documentation is available, so my approach may be entirely wrong:
using SkiaSharp;
public static byte[] Resize(byte[] fileContents, int maxWidth, int maxHeight)
{
using MemoryStream ms = new(fileContents);
using SKBitmap sourceBitmap = SKBitmap.Decode(ms); // <-- EXCEPTION HERE ON LARGER FILES
int height = Math.Min(maxHeight, sourceBitmap.Height);
int width = Math.Min(maxWidth, sourceBitmap.Width);
var quality = SKFilterQuality.High;
using SKBitmap scaledBitmap = sourceBitmap.Resize(new SKImageInfo(width, height), quality);
using SKImage scaledImage = SKImage.FromBitmap(scaledBitmap);
using SKData data = scaledImage.Encode();
return data.ToArray();
}
In the Razor component:
foreach (var file in e.GetMultipleFiles(maxAllowedFiles))
{
// Convert uploaded file into a byte array
await using var memoryStream = new MemoryStream();
await file.OpenReadStream(maxFileSizeBytes).CopyToAsync(memoryStream);
var imageByteArray = memoryStream.ToArray();
await memoryStream.DisposeAsync();
// Use byte array to generate a resized image
var resizedFullSizeBytes = EventFinderShared.Images.ImageDimensionCalculation.Resize(imageByteArray, maxWidthOrHeight, maxWidthOrHeight); // <== Error here
var resizedThumbnailBytes = EventFinderShared.Images.ImageDimensionCalculation.Resize(imageByteArray, thumbnailWidthOrHeight, thumbnailWidthOrHeight);
// Further usage removed for brevity...
}
Using the debugger, byte[] fileContents
definitely is not null, so I have no idea what's occurring.
System.ArgumentNullException
HResult=0x80004003
Message=Value cannot be null. Arg_ParamName_Name
Source=SkiaSharp
StackTrace:
at SkiaSharp.SKManagedStream.OnReadManagedStream(IntPtr buffer, IntPtr size)
at SkiaSharp.SKAbstractManagedStream.ReadInternal(IntPtr s, Void* context, Void* buffer, IntPtr size)
at SkiaSharp.SkiaApi.sk_codec_new_from_stream(IntPtr stream, SKCodecResult* result)
at SkiaSharp.SKCodec.Create(SKStream stream, SKCodecResult& result)
at SkiaSharp.SKBitmap.Decode(Stream stream)
at EventFinderShared.Images.ImageDimensionCalculation.Resize(Byte[] fileContents...
The issue was due to a bug in SkiaSharp 2.88.2. Updating to 2.88.3 has solved the problem, although it appears that related issues may still exist.