从流在c#中创建缩略图

从流在c#中创建缩略图,c#,image,C#,Image,经过3个小时的调试和搜索,我得到了这个 public Stream ResizeImageToThumbnail(Stream-imageStream,int-width) { var image=image.FromStream(imageStream); 变量高度=(宽度*image.height)/image.width; var thumbnail=image.GetThumbnailImage(宽度、高度、null、IntPtr.Zero); 使用var thumbnailStream

经过3个小时的调试和搜索,我得到了这个

public Stream ResizeImageToThumbnail(Stream-imageStream,int-width)
{
var image=image.FromStream(imageStream);
变量高度=(宽度*image.height)/image.width;
var thumbnail=image.GetThumbnailImage(宽度、高度、null、IntPtr.Zero);
使用var thumbnailStream=newmemoryStream();
保存(thumbnailStream,ImageFormat.Jpeg);
返回thumbnailStream;
}
问题是,它返回异常

ArgumentException:参数无效

参数为
file.OpenFileStream()其中
文件
格式文件

我没有主意了

编辑

请求的代码:


foreach(model.UploadedImages中的var item)//item=ifformfile,仅允许从HTML结尾使用图像
{
使用var ms=item.OpenReadStream();
_service.AttachImage(newId,ms,item.FileName);
ms.Position=0;
_service.AttachThumb(newId,ms,item.FileName);//无法访问封闭流异常
}
编辑2

AttachThumb正在使用封闭流,返回异常(检查注释)。似乎
ResizeImageToThumbnail
返回关闭的流

public void AttachThumb(Guid id、流imageStream、字符串imageName)
{
Post Post=GetPost(id);
ObjectId imageId=\u gridFS.UploadFromStream(imageName,ResizeImageToHumbail(imageStream,640));//无法使用封闭流
post.imagestumbs.Add(imageId.ToString());
var filter=Builders.filter.Eq(x=>x.Id,Id);
var update=Builders.update.Set(“imagestumbs”,post.imagestumbs);
_posts.UpdateOne(过滤器,更新);
}
公共流ResizeImageToThumbnail(流imageStream,int-width)
{
var image=image.FromStream(imageStream);
变量高度=(宽度*image.height)/image.width;
var thumbnail=image.GetThumbnailImage(宽度、高度、null、IntPtr.Zero);
使用var thumbnailStream=newmemoryStream();
保存(thumbnailStream,ImageFormat.Jpeg);
返回thumbnailStream;
}

首先将文件内容复制到流中,然后使用该流。倒带中间的流。请注意,两个Attach*方法不能异步访问流。否则,您必须首先在内存中创建第二个副本

foreach (var item in model.UploadedImages)
{
    // Copy content in to stream
    using (MemoryStream stream = new MemoryStream())
    {
        item.CopyTo(stream);

        // Rewind and use
        stream.Position = 0;
        _service.AttachImage(newId, stream, item.FileName);
        
        // Rewind and use
        stream.Position = 0;
        _service.AttachThumb(newId, stream, item.FileName);
    }
}

正如用户Jimi所指出的,您必须从
ResizeImageToThumbnail
方法中删除
using
子句。否则,该方法将返回已处理的
内存流

public Stream ResizeImageToThumbnail(Stream imageStream, int width)
{
    var image = Image.FromStream(imageStream);

    var height = (width * image.Height) / image.Width;
    var thumbnail = image.GetThumbnailImage(width, height, null, IntPtr.Zero);

    // Bad: using var thumbnailStream = new MemoryStream();
    // Remove using
    var thumbnailStream = new MemoryStream(); 
    thumbnail.Save(thumbnailStream, ImageFormat.Jpeg);
    return thumbnailStream;
}
然后,在外部处理流:

public void AttachThumb(Guid id, Stream imageStream, string imageName)
{
    Post post = GetPost(id);

    using var thumbnailStream = ResizeImageToThumbnail(imageStream, 640);
    // rewind stream
    thumbnailStream.position = 0;
    ObjectId imageId = _gridFS.UploadFromStream(imageName, thumbnailStream); 

    ...


您可以通过不使用
ResizeImageToThumbnail
方法来创建流,而是在外部创建流,并将其作为参数传递给
ResizeImageToThumbnail
,从而改进此方法的设计。因此,
ResizeImageToThumbnail
的调用者随后负责创建和处理流。

将文件存储到光盘以检查它是否是有效的图像文件。这是什么图像文件?@NineBerry它的jpg。当我将其直接转储到数据库时,它工作正常。但显示像缩略图这样巨大的文件是个坏主意。用记事本打开图像。图像应具有显示图像类型的ASCII标题。图像可能与图形卡不兼容。另一种可能是该流是Base64流,需要转换为字节。请尝试从IFormFile复制到MemoryStream,然后从MemoryStream创建映像。您是否尝试两次访问与流相同的上载文件?如果是,则需要将流的position属性设置为0,从而在两者之间倒带流。仍然断开。但我知道这是什么。进行了编辑。请参见@JimiFigured的备注。但我不知道如何说服编译器不要处理它。只需在ResizeImageToHumbnail方法中使用
删除关键字
。在将流交给
\u gridFS.UploadFromStream()
之前,您可能必须倒带流。我更新了我的答案。使用流意味着始终意识到它们具有当前位置。如果你想处理他们的所有内容,你需要定期倒带这个位置
public void AttachThumb(Guid id, Stream imageStream, string imageName)
{
    Post post = GetPost(id);

    using var thumbnailStream = ResizeImageToThumbnail(imageStream, 640);
    // rewind stream
    thumbnailStream.position = 0;
    ObjectId imageId = _gridFS.UploadFromStream(imageName, thumbnailStream); 

    ...