[英]Create thumbnail in c# from stream
经过 3 个小时的调试和搜索,我有了这个。
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);
using var thumbnailStream = new MemoryStream();
thumbnail.Save(thumbnailStream, ImageFormat.Jpeg);
return thumbnailStream;
}
问题是,它返回异常
ArgumentException:参数无效。
在
var image = Image.FromStream(imageStream);
参数为file.OpenFileStream();
其中file
是IFormFile
。
我没主意了。
编辑
要求的代码:
foreach (var item in model.UploadedImages) //item = IFormFile, image only allowed from HTML's end
{
using var ms = item.OpenReadStream();
_service.AttachImage(newId, ms, item.FileName);
ms.Position = 0;
_service.AttachThumb(newId, ms, item.FileName); //cannot access a closed stream exception
}
编辑 2
AttachThumb 使用封闭的 stream,返回异常(检查注释)。 ResizeImageToThumbnail
似乎返回关闭的 stream。
public void AttachThumb(Guid id, Stream imageStream, string imageName)
{
Post post = GetPost(id);
ObjectId imageId = _gridFS.UploadFromStream(imageName, ResizeImageToThumbnail(imageStream, 640)); //cannot use closed stream
post.ImagesThumbs.Add(imageId.ToString());
var filter = Builders<Post>.Filter.Eq(x => x.Id, id);
var update = Builders<Post>.Update.Set("ImagesThumbs", post.ImagesThumbs);
_posts.UpdateOne(filter, update);
}
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);
using var thumbnailStream = new MemoryStream();
thumbnail.Save(thumbnailStream, ImageFormat.Jpeg);
return thumbnailStream;
}
首先将文件内容复制到 stream 中,然后使用该 stream。 在两者之间倒带 stream。 请注意,两个 Attach* 方法不得异步访问 stream。 否则,您必须先创建第二个内存副本。
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
子句。 否则,该方法返回一个已经释放的MemoryStream
:
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;
}
然后将 stream 放在外面:
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
方法创建 stream 而是在外部创建 stream 并将其作为参数传递给ResizeImageToThumbnail
来改进此设计。 所以ResizeImageToThumbnail
的调用者然后负责创建和处置 stream。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.