IBrowserFile FromIMageFileAsync 图像不完整
IBrowserFile FromIMageFileAsync incomplete image
我正在将图像上传到我的应用程序并且我正在使用此代码:
public static async Task<string> GetThumbnailAndImage(InputFileChangeEventArgs e)
{
var file = e.File;
var imageTmp = await file.RequestImageFileAsync("jpg", 200, 200);
return image = await UploadMedia(imageTmp);
}
public static async Task<string> UploadMedia(IBrowserFile file)
{
byte[] bytes = new byte[file.Size];
var stream = file.OpenReadStream(int.MaxValue);
await stream.ReadAsync(bytes);
return Convert.ToBase64String(bytes);
}
这里的问题是,根据我要求的像素,图像是部分上传的,例如:
我期待左图,但得到的是右图。有谁知道可能导致此问题的原因吗?
最佳
看来我们不能使用Stream.ReadAsync()方法。使用“MaxAllowedSize”参数覆盖时,IBrowserFile 的框架代码中存在错误。这总是在缓冲区的开头写入字节,并且不会将位置指针移动到上一个缓冲区写入的末尾以供下一次读取。这导致实际上只有一部分图像被流式传输。
我的解决办法是读取上传的图片文件流,然后复制到内存流中,转换成字节数组。
像这样:
public async Task<string> UploadMedia(IBrowserFile file)
{
long maxFileSize = 1024 * 1024 * 5; // 5 MB or whatever, don't just use max int
var readStream = file.OpenReadStream(maxFileSize);
var buf = new byte[readStream.Length];
var ms = new MemoryStream(buf);
await readStream.CopyToAsync(ms);
var buffer = ms.ToArray();
return Convert.ToBase64String(buffer);
}
@TLP 回答解决了问题,但是如果我们按照微软的安全建议在上传时不将文件读入内存,它仍然可以改进:https://docs.microsoft.com/en-us/aspnet/core/blazor/file-uploads?view=aspnetcore-6.0&pivots=server
因此解决此问题的正确方法是将文件存储在临时文件中,在将其转换为字节数组后关闭文件流并删除 tmp 文件:
public static async Task<string> UploadMedia(IBrowserFile file)
{
var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
await using var fs = new FileStream(path, FileMode.Create);
await file.OpenReadStream(file.Size).CopyToAsync(fs);
var bytes = new byte[file.Size];
fs.Position = 0;
await fs.ReadAsync(bytes);
fs.Close();
File.Delete(path);
return Convert.ToBase64String(bytes);
}
我正在将图像上传到我的应用程序并且我正在使用此代码:
public static async Task<string> GetThumbnailAndImage(InputFileChangeEventArgs e)
{
var file = e.File;
var imageTmp = await file.RequestImageFileAsync("jpg", 200, 200);
return image = await UploadMedia(imageTmp);
}
public static async Task<string> UploadMedia(IBrowserFile file)
{
byte[] bytes = new byte[file.Size];
var stream = file.OpenReadStream(int.MaxValue);
await stream.ReadAsync(bytes);
return Convert.ToBase64String(bytes);
}
这里的问题是,根据我要求的像素,图像是部分上传的,例如:
我期待左图,但得到的是右图。有谁知道可能导致此问题的原因吗?
最佳
看来我们不能使用Stream.ReadAsync()方法。使用“MaxAllowedSize”参数覆盖时,IBrowserFile 的框架代码中存在错误。这总是在缓冲区的开头写入字节,并且不会将位置指针移动到上一个缓冲区写入的末尾以供下一次读取。这导致实际上只有一部分图像被流式传输。
我的解决办法是读取上传的图片文件流,然后复制到内存流中,转换成字节数组。
像这样:
public async Task<string> UploadMedia(IBrowserFile file)
{
long maxFileSize = 1024 * 1024 * 5; // 5 MB or whatever, don't just use max int
var readStream = file.OpenReadStream(maxFileSize);
var buf = new byte[readStream.Length];
var ms = new MemoryStream(buf);
await readStream.CopyToAsync(ms);
var buffer = ms.ToArray();
return Convert.ToBase64String(buffer);
}
@TLP 回答解决了问题,但是如果我们按照微软的安全建议在上传时不将文件读入内存,它仍然可以改进:https://docs.microsoft.com/en-us/aspnet/core/blazor/file-uploads?view=aspnetcore-6.0&pivots=server
因此解决此问题的正确方法是将文件存储在临时文件中,在将其转换为字节数组后关闭文件流并删除 tmp 文件:
public static async Task<string> UploadMedia(IBrowserFile file)
{
var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
await using var fs = new FileStream(path, FileMode.Create);
await file.OpenReadStream(file.Size).CopyToAsync(fs);
var bytes = new byte[file.Size];
fs.Position = 0;
await fs.ReadAsync(bytes);
fs.Close();
File.Delete(path);
return Convert.ToBase64String(bytes);
}