最近在开发一套系统,很多地方用到了缩略图,然而不同的地方用到的尺寸又不一样,上传的时候生成缩略图就没有意义了,因为你不知道会使用到哪些尺寸,于是想到即时生成的办法,前端判断图片是否存在,如果不存在则调用接口生成缩略图,同时接口返回缩略图的数据流。
本来功能都开发完成,可以达到目的,但是在会员头像使用Png生成缩略图是遇到了一个问题,就是生成的缩略图不是透明的,变成黑底色了。更奇怪的问题是并不是所有png图片都这样,同一张图片在不同的地方也有不一样的效果。
没有修改之前的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | /// <summary> /// 访问图片,接口调用方式 https://您的域名/WebApi/common/200/image%2F2022-06%2Fbb372369c3ad4d458ad2aee6c00ca4bd.png <br> ///其中200是图片宽度,后面是图片的相对路径 /// </summary> /// <param name="width">所访问图片的宽度,高度自动缩放,大于原图尺寸或者小于等于0返回原图</param> /// <param name="name">所要访问图片的名称或者相对地址</param> /// <returns>图片</returns> [HttpGet] [Route( "{width}/{name}" )] public IActionResult GetImage( int width, string name) { var errorImage = "/static/common/images/404.png" ; //没有找到图片 if (name.IsEmptyString()) { name = errorImage; } else { name = HttpUtility.UrlDecode(name, Encoding.GetEncoding( "utf-8" )); name = name.Replace( "/" , "\\" ); if (name.StartsWith( "\\" )) { name = name.Substring(1); } } var contentTypeStr = "image/jpeg" ; var ext = Path.GetExtension(name); //未知的图片类型 if (!FileHelper.IsImageExt(ext)) { name = errorImage; } else { contentTypeStr = FileHelper.GetContentType(ext); } bool isThum = false ; //是否是缩略图 var thumname = name; //缩略图路径 bool saveThum = false ; //原图 if (width <= 0) { using ( var sw = objectStorage.GetObject(name)) { var bytes = new byte [sw.Length]; sw.Read(bytes, 0, bytes.Length); sw.Close(); return new FileContentResult(bytes, contentTypeStr); } } else { thumname = name.Replace(ext, "_" + width + ext); isThum = true ; } if (name != errorImage && !objectStorage.ExistObject(name)) { name = errorImage; } if (isThum && !objectStorage.ExistObject(thumname)) { saveThum = true ; } //缩小图片 using ( var imgBmp = new Bitmap(Image.FromStream(objectStorage.GetObject(name)))) { //找到新尺寸 var oWidth = imgBmp.Width; var oHeight = imgBmp.Height; var height = oHeight; if (width > oWidth) { width = oWidth; } else { height = width * oHeight / oWidth; } var newImg = new Bitmap(imgBmp, width, height); newImg.SetResolution(72, 72); var ms = new MemoryStream(); newImg.Save(ms, ImageFormat.Bmp); if (saveThum) {<br> //这里是调用的类似OSS保存图片的方法 objectStorage.PutObject(thumname, ms); ms.Position = 0; } var bytes = ms.GetBuffer(); ms.Close(); return new FileContentResult(bytes, contentTypeStr); } } |
代码如上,表面上看起来看不出来问题,后来我认真检查了一下代码,发现newImg.Save(ms, ImageFormat.Bmp);这句代码有点问题,为什么是固定的bmp格式,于是我将这句代码改成如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | switch (ext.ToLower()) { case ".jpg" : case ".jpeg" : case ".jpe" : case ".jfif" : newImg.Save(ms, ImageFormat.Jpeg); break ; case ".png" : newImg.Save(ms, ImageFormat.Png); break ; case ".gif" : newImg.Save(ms, ImageFormat.Gif); break ; case ".tif" : case ".tiff" : newImg.Save(ms, ImageFormat.Tiff); break ; case ".bmp" : case ".wbmp" : newImg.Save(ms, ImageFormat.Bmp); break ; default : newImg.Save(ms, ImageFormat.Jpeg); break ; } |
问题解决,原来文件流里面也是要指定文件保存的格式的,不然就会出现想不到的问题。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!