SkiaSharp SKBitmap.Decode 值不能为空。 (参数\'缓冲区\')

分享于2022年10月08日 .net-6.0 blazor-server-side c# memorystream skiasharp 问答
【问题标题】:SkiaSharp SKBitmap.Decode() Value cannot be null. (Parameter 'buffer')SkiaSharp SKBitmap.Decode() 值不能为空。 (参数\'缓冲区\')
【发布时间】:2022-10-06 20:37:45
【问题描述】:

我正在尝试从 Blazor InputFile 组件上传多个图像:


进入内存后,我需要使用 SkiaSharp 将它们的大小调整为最大 1000 像素宽/高。我为此创建了一个辅助方法,但它似乎在任何超过大约 4MB 的图像上都失败了。我从搜索加上任何(相当缺乏)可用的 Microsoft 文档将以下逻辑拼凑在一起,所以我的方法可能完全错误:

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

在 Razor 组件中:

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...
}

使用调试器, byte[] fileContents 绝对不为空,所以我不知道发生了什么。

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...

【解决方案1】:

问题是由于 bug in SkiaSharp 2.88.2。更新到 2.88.3 已经解决了这个问题,尽管看起来相关问题可能仍然存在。

【讨论】: