[英]Image provider in ASP.NET Core 3.1
我有一个基于 ASP.NET Core 的名为“存储”的 Web API,使用C#
编写。 此应用程序旨在为许多带有图像的网络应用程序提供服务。 使用我拥有的其他应用程序可以使用 HTTP 请求从存储中请求图像。
为了从辅助/消费应用程序与我的存储应用程序交互,我创建了一个自定义文件提供程序实现,它允许我像这样访问这些图像
public class MyCustomImagesProvider : IFileProvider
{
private readonly IHttpClientFactory ClientFactory;
public MyCustomImagesProvider(IHttpClientFactory clientFactory)
{
ClientFactory = clientFactory;
}
public IFileInfo GetFileInfo(string subpath)
{
try
{
var client = ClientFactory.CreateClient("client-name");
Uri url = new Uri("https://storage.mydomain.com", $"api/files/get?name={subpath}");
var result = client.GetAsync(url).Result;
result.EnsureSuccessStatusCode();
string filename = Path.GetFileName(subpath);
DateTime lastModifiedAt = (result.Content.Headers.LastModified?.DateTime) ?? DateTime.Now;
var stream = result.Content.ReadAsStreamAsync().Result;
return new MyCustomFileInfo(stream, filename, lastModifiedAt);
}
catch
{
}
return new MyCustomFileInfo
{
Exists = false
};
}
public IDirectoryContents GetDirectoryContents(string subpath) => throw new NotImplementedException();
public IChangeToken Watch(string filter) => throw new NotImplementedException();
}
我的一些应用程序只需要图像的缩略图,而其他应用程序需要图像的全尺寸和/或缩略图。 后来,对于某些应用程序,我什至可能还需要一个中等大小的图像(同一图像可能有 4 个不同大小的图像。)磁盘空间限制正在成为一个问题,因为我必须将同一个图像复制到多个文件中(每个文件一个)以容纳我所有的应用程序。
换句话说,如果我有一个名为“abc_fullsize.jpg”的文件,那么我需要创建和存储“abc_thumbnail.jpg”和“abc_midside.jpg”,这需要大量磁盘空间。
题
动态创建这些图像而不是在桌面上创建它们是否有效?
我想我将有一个ThumbnailImageProvider
, MidsizeImageProvider
和FullsizeImageProvider
每个就送需要最大尺寸为存储应用程序和存储的应用程序将读取来自台全尺寸的图像,然后用调整后的图像响应。 这是ThumbnailImageProvider
的示例
public class ThumbnailImageProvider : IFileProvider
{
private readonly IHttpClientFactory ClientFactory;
public ThumbnailImageProvider(IHttpClientFactory clientFactory)
{
ClientFactory = clientFactory;
}
public IFileInfo GetFileInfo(string subpath)
{
try
{
var client = ClientFactory.CreateClient("client-name");
// Note the max-width=250 parameter here would tell the API that I need this image recreated on the fly with max width of 250.
Uri url = new Uri("https://storage.mydomain.com", $"api/files/get?name={subpath}&maxWidth=250");
var result = client.GetAsync(url).Result;
result.EnsureSuccessStatusCode();
string filename = Path.GetFileName(subpath);
DateTime lastModifiedAt = (result.Content.Headers.LastModified?.DateTime) ?? DateTime.Now;
var stream = result.Content.ReadAsStreamAsync().Result;
return new MyCustomFileInfo(stream, filename, lastModifiedAt);
}
catch
{
}
return new MyCustomFileInfo
{
Exists = false
};
}
public IDirectoryContents GetDirectoryContents(string subpath) => throw new NotImplementedException();
public IChangeToken Watch(string filter) => throw new NotImplementedException();
}
api/files/get
端点上的操作方法将响应以下操作
[HttpGet("get")]
public IActionResult Get(string name, int? maxWidth)
{
IFileInfo fileInfo = FileProvider.GetFileInfo(name);
if (!fileInfo.Exists)
{
return NotFound();
}
if(maxWidth.HasValue && maxWidth > 1)
{
Image image = ImageProcessor.GetResizedImage(fileInfo.CreateReadStream(), maxWidth.Value, out ImageFormat imageFormat);
using var memoryStream = new MemoryStream();
image.Save(memoryStream, imageFormat);
string extension = Path.GetExtension(fileInfo.Name);
string rawFilename = Path.GetFileNameWithoutExtension(fileInfo.Name);
string filename = $"{rawFilename}-{maxWidth}{extension}";
return File(memoryStream, "image/jpeg", filename, fileInfo.LastModified, null);
}
return File(fileInfo.CreateReadStream(), "image/jpeg", fileInfo.Name, fileInfo.LastModified, null);
}
我认为您最好将您的逻辑应用于中间件。 看看aspnet的静态文件中间件是如何工作的:
你的方法有两个问题:
所以我的建议是在磁盘上缓存图像(或使用输出缓存时的 blob 存储)-> https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore- 3.1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.