前言
在我们日常开发中,附件的上传下载是必备的功能组件,那么在延伸一下功能,图片类型的文件,我们可以做一些缩略图功能。
关于缩略图的方案,大致方向有两种:第一种是图片服务器直接存放多张图片,另外一种则是只存一张图片,然后通过nginx或者对文件的直接压缩返回。很明显,前者浪费空间,后者才是我们想要的,如果你们生产环境空间很足,那你们也可以搞第一种。
关于用nginx还是直接对文件进行压缩返回,还是要根据自己生产环境的情况来定制开发方案,由于我们生产环境是windows的,查阅过nginx一些关于缩略图的资料,绝大部分是linux的,windows版的略微复杂,所以这里我们选择直接对文件进行压缩返回。
开始
这里我是直接对之前的范例《minio:实现简单上传跟下载(netcore版本)》代码进行简单调整,主要还是对下载接口重新调整。
大致的改造思想:从minio获取文件流=》判断文件流是否为图片类型=》将图片调整成自己想要的大小及分辨率然后返回新的文件
核心代码
/// <summary>
/// 下载附件(支持缩略图)
/// </summary>
/// <param name="fileName"></param>
/// <param name="width">所访问图片的宽度,放空则自动缩放</param>
/// <param name="height">所访问图片的高度,放空则自动缩放</param>
/// <returns></returns>
[HttpGet("/file/DownloadFile")]
public async Task<IActionResult> DownloadFile(string fileName, int? width, int? height)
{
var memoryStream = new MemoryStream();
var contentType = GetContentType(fileName);
string fileExt = Path.GetExtension(fileName);
try
{
await _client.StatObjectAsync(bucketName, fileName);
await _client.GetObjectAsync(bucketName, fileName,
(stream) =>
{
stream.CopyTo(memoryStream);
});
memoryStream.Position = 0;
#region 图片类型文件则可进行缩略操作
if (IsImage(memoryStream))
{
//缩放图片
using (var imgBmp = new Bitmap(memoryStream))
{
//原尺寸
var oldWidth = imgBmp.Width;
var oldHeight = imgBmp.Height;
int newWidth = 0, newHeigt = 0;
if (width.HasValue || height.HasValue)
{
if (width.HasValue && !height.HasValue)//按宽度等比例缩放
{
newWidth = width.Value;
newHeigt = width.Value * oldHeight / oldWidth;
}
else if (!width.HasValue && height.HasValue)//按高度等比例缩放
{
newHeigt = height.Value;
newWidth = height.Value * oldWidth / oldHeight;
}
else
{
newWidth = width.Value;
newHeigt = height.Value;
}
}
else
{
newWidth = oldWidth;
newHeigt = oldHeight;
}
var newImg = new Bitmap(imgBmp, newWidth, newHeigt);
//newImg.SetResolution(72, 72);调整分辨率
var ms = new MemoryStream();
newImg.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
var bytes = ms.GetBuffer();
ms.Close();
return File(bytes, fileObj?.ContentType, DateTime.Now.ToString("yyyyMMddmmss") + fileObj?.FileExt);
}
}
#endregion
}
catch (MinioException e)
{
Console.Out.WriteLine("下载附件发生错误: " + e);
}
return File(memoryStream, contentType, DateTime.Now.ToString("yyyyMMddmmss") + fileExt);
}
判断文件流是否为图片类型代码
IsImage.cs
/// <summary>
/// 判断文件是否为图片
/// </summary>
/// <param name="stream">文件流</param>
/// <returns>返回结果</returns>
private static bool IsImage(Stream stream)
{
try
{
System.Drawing.Image img = System.Drawing.Image.FromStream(stream);
return true;
}
catch
{
return false;
}
}
测试
重新编译,然后准备好两个文件,一个是图片类型,一个文档类型的
测试图片缩略功能
原图:
缩放后的图:
缩放成功!
测试判断文档功能
大功告成,886
完整minio范例项目地址已上传github:https://github.com/shaojiayong/miniodemo