我有以下控制器,该控制器从视图接收文件时会生成一个缩略图,并将图像和缩略图分别保存到数据库中
public async Task<ActionResult> FileUpload(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var logo = new Logo() { LogoGuid = Guid.NewGuid() };
var clinica = await GetClinicaAsync();
if (IsClinicNonexistent(clinica))
{
db.Logos.Add(logo);
clinica.LogoGuid = logo.LogoGuid;
}
else
logo = await db.Logos.FirstOrDefaultAsync(l => l.LogoGuid == clinica.LogoGuid);
logo.LogoImage = GetImage(file);
logo.Thumbnail = GetThumbnail(file);
db.SaveChanges();
}
return RedirectToAction("Arquivos");
}
对于此错误,请调用方法:
private byte[] GetThumbnail(HttpPostedFileBase file)
{
var image = Image.FromStream(file.InputStream);
var thumbnailSize = GetThumbnailSize(image);
var memoryStream = new MemoryStream();
var thumbnail = image.GetThumbnailImage(thumbnailSize.Width, thumbnailSize.Height, null, IntPtr.Zero);
image.Save(memoryStream, ImageFormat.Jpeg);
return memoryStream.ToArray();
}
该代码配置在运行该行时会产生错误
var image = Image.FromStream(file.InputStream);
错误是:“ System.ArgumentException:参数无效。”
我可以参考的所有文档使我相信,它们在语义和逻辑上都是正确的,但是仍然存在错误...
但是,有趣的是,如果移动会产生错误的转换行,请执行调用方法,特别是从头开始:
public async Task<ActionResult> FileUpload(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var logo = new Logo() { LogoGuid = Guid.NewGuid() };
var clinica = await ClinicaAsync();
var image = Image.FromStream(file.InputStream);
没有错误。请注意,转换行位于上面代码的最后一行中,因此位于控制器的开头。同样,如果我将该行进一步向下移动,但仍在控制器中,则会再次出现错误...
如何在GetThumbnail方法中保持该行在逻辑上的位置?
作为附加参考,GetImage方法是:
private byte[] GetImage(HttpPostedFileBase file)
{
using (var br = new BinaryReader(file.InputStream))
return br.ReadBytes(file.ContentLength);
}
答案 0 :(得分:1)
您应该知道的第一件事是Image.FromStream()
需要尚未被读取的流(MemoryStream
,InputStream
等),或者位置被重置为开始使用Seek()
方法。
首先,在使用GetThumbnail()
属性或Position
调用Seek()
方法之前,尝试重置指针:
// alternative 1
logo.LogoImage = GetImage(file);
file.InputStream.Position = 0;
logo.Thumbnail = GetThumbnail(file);
// alternative 2
logo.LogoImage = GetImage(file);
file.InputStream.Seek(0, SeekOrigin.Begin);
logo.Thumbnail = GetThumbnail(file);
如果这不起作用,可能的原因是您在Image.FromStream()
已经HttpPostedFileBase.InputStream
使用(并处置)了BinaryReader
后调用Dispose()
( using
语句会自动调用它),从而引发异常。
您可以使用Stream.CopyTo()
从MemoryStream
创建HttpPostedFileBase.InputStream
的副本,如下例:
public async Task<ActionResult> FileUpload(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var logo = new Logo() { LogoGuid = Guid.NewGuid() };
var clinica = await GetClinicaAsync();
var ms = new MemoryStream();
file.InputStream.CopyTo(ms); // copy HTTP stream to memory stream
if (IsClinicNonexistent(clinica))
{
db.Logos.Add(logo);
clinica.LogoGuid = logo.LogoGuid;
}
logo.LogoImage = GetImage(file);
ms.Position = 0; // make sure the stream is read from beginning
logo.Thumbnail = GetThumbnail(ms);
db.SaveChanges();
}
return RedirectToAction("Arquivos");
}
然后应更改GetThumbnail()
参数以接受从HTTP流复制的MemoryStream
:
// get image from memory stream
private byte[] GetThumbnail(MemoryStream file)
{
var image = Image.FromStream(ms);
var thumbnailSize = GetThumbnailSize(image);
var thumbnail = image.GetThumbnailImage(thumbnailSize.Width, thumbnailSize.Height, null, IntPtr.Zero);
image.Save(file, ImageFormat.Jpeg);
return file.ToArray();
}
注意:您还可以将流作为图像文件保存在磁盘上,然后使用Server.MapPath()
进行读取以生成缩略图。
相关问题:
Image.FromStream(PostedFile.InputStream) Fails. (Parameter is not valid.) (AsyncFileUpload))