做项目时发现客户有时传的好多海报大图,前台展示轮播几十张会加载很慢,以前只用过php的timthumb,这就自己写了一个asp.net版的使用
调用方式和他类似,
Original:1 or 0是否为返回原图Url
Compress压缩比0-100 100最好
例如:http://yourServer/handlers/thumb.ashx?ImgUrl=/Upload/Poster/20171205/17120511041625.jpg&Width=185&Height=300&Compress=70&Original=
会直接返回图片数据写入到页面内,而且简单做了下缓存处理,就是如果同一个地址同一个宽高的图片,每次处理前会先判断是否已经处理过,如果已经处理过直接找到那个图片返回去就行,省的每次都处理,文件越来越多。
namespace WebApplication.Handlers { /// <summary> /// 裁剪压缩图片 /// </summary> public class Thumb : IHttpHandler { public string SavePath = "/Upload"; public string ThumbImageDir = "Thumb"; public void ProcessRequest(HttpContext context) { string err = string.Empty; string original = GetRequestValue("Original"); //返回原图URL 1 0 string imgUrl = GetRequestValue("ImgUrl"); string width = GetRequestValue("Width"); string height = GetRequestValue("Height"); string compress = GetRequestValue("Compress");//压缩比、1-100 if (StrEmpty(imgUrl)) err += " Image url error"; if (StrEmpty(width)) err += " Please enter image width"; if (StrEmpty(height)) err += " Please enter image height"; if (!StrEmpty(err)) { context.Response.Write(err); context.Response.End(); } //视情况而定,如果是图片完整路径就直接imgUrl就好 此项目中都是相对路径 imgUrl = "http://" + context.Request.Url.Authority + imgUrl; string imgMd5 = GetFileSaveName(imgUrl + "_" + width + "x" + height); //保存的文件名Url的MD5加上宽x高 string fileExt = Path.GetExtension(imgUrl); //返回原图地址 if (string.Compare(original, "1") == 0) { context.Response.Write(imgUrl); context.Response.End(); } context.Response.ContentType = "image/png"; string thumbImgPath = SavePath + "/" + ThumbImageDir + "/" + imgMd5 + "_thumb" + fileExt; //压缩后的图片路径 string strResizeImgPath = HttpContext.Current.Server.MapPath(thumbImgPath); string serverThumbImgDir = HttpContext.Current.Server.MapPath(SavePath + "/" + ThumbImageDir); if (!Directory.Exists(serverThumbImgDir)) Directory.CreateDirectory(serverThumbImgDir); //如果缩略图已经存在 l if (File.Exists(HttpContext.Current.Server.MapPath(thumbImgPath))) { WriteImg(strResizeImgPath); } Stream imgSavePath = HttpDownloadFile(imgUrl); if (imgSavePath == null) { err += " Image url error"; context.Response.Write(err); context.Response.End(); } bool flag = false; Image thumbImg = Image.FromStream(imgSavePath); int imgWidth = thumbImg.Width; int imgHeight = thumbImg.Height; int maxWidth = Convert.ToInt32(width); int maxHeight = Convert.ToInt32(height); if (imgWidth > imgHeight) //如果宽度超过高度以宽度为准来调整 { if (imgWidth > maxWidth) //如果图片宽度超过限制 { int toImgWidth = maxWidth; //图片调整后的宽度 int toImgHeight = imgHeight / (int)(imgWidth / toImgWidth); //图片调整后的高度 Bitmap img = new Bitmap(thumbImg, int.Parse(toImgWidth.ToString()), int.Parse(toImgHeight.ToString())); if (StrEmpty(compress)) img.Save(strResizeImgPath); //保存调整大小后的图片 else Compress(img, strResizeImgPath, Convert.ToInt32(compress)); //压缩 flag = true; } } else { if (imgHeight > maxHeight) { int toImgHeight = maxHeight; int toImgWidth = imgWidth / (int)(imgHeight / toImgHeight); Bitmap img = new Bitmap(thumbImg, int.Parse(toImgWidth.ToString()), int.Parse(toImgHeight.ToString())); if (StrEmpty(compress)) img.Save(strResizeImgPath); //保存调整大小后的图片 else Compress(img, strResizeImgPath, Convert.ToInt32(compress)); //压缩 flag = true; } } if (flag) { WriteImg(strResizeImgPath); } else context.Response.Write("Resize Faild"); } public void WriteImg(string imgPath) { var imgStream = new FileStream(imgPath, FileMode.Open); byte[] byteImg = new byte[imgStream.Length]; imgStream.Read(byteImg, 0, byteImg.Length); imgStream.Close(); HttpContext.Current.Response.OutputStream.Write(byteImg, 0, byteImg.Length); HttpContext.Current.Response.End(); } /// <summary> /// 获取缩略图文件保存的文件名 /// </summary> /// <param name="url">图片URL</param> /// <returns></returns> public string GetFileSaveName(string url) { return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(url, "MD5"); } /// <summary> /// 获取文件MD5值 /// </summary> /// <param name="fileStream"></param> /// <returns></returns> public string GetFileMd5(Stream fileStream) { MD5 md5 = new MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(fileStream); StringBuilder sb = new StringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); } /// <summary> /// 下载URL文件 返回Stream /// </summary> /// <param name="url">文件URL</param> /// <returns></returns> public Stream HttpDownloadFile(string url) { if (!url.Contains("http://") && !url.Contains("https://")) { url = "http://" + url; } try { HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url); myRequest.Timeout = 10000; //超时时间10秒 HttpWebResponse res = (HttpWebResponse)myRequest.GetResponse(); if (res.StatusCode == HttpStatusCode.OK) { Stream responseStream = res.GetResponseStream(); MemoryStream ms = new MemoryStream(); byte[] bArr = new byte[1024]; int size = responseStream.Read(bArr, 0, (int)bArr.Length); while (size > 0) { ms.Write(bArr, 0, size); size = responseStream.Read(bArr, 0, (int)bArr.Length); } return ms; } else return null; } catch { return null; } } private ImageCodecInfo GetEncoderInfo(String mimeType) { int j; ImageCodecInfo[] encoders; encoders = ImageCodecInfo.GetImageEncoders(); for (j = 0; j < encoders.Length; ++j) { if (encoders[j].MimeType == mimeType) return encoders[j]; } return null; } /// <summary> /// 图片压缩(降低质量以减小文件的大小) /// </summary> /// <param name="srcBitmap">传入的Bitmap对象</param> /// <param name="destStream">压缩后的Stream对象</param> /// <param name="level">压缩等级,0到100,0 最差质量,100 最佳</param> public void Compress(Bitmap srcBitmap, Stream destStream, long level) { System.Drawing.Imaging.ImageCodecInfo myImageCodecInfo; System.Drawing.Imaging.Encoder myEncoder; EncoderParameter myEncoderParameter; EncoderParameters myEncoderParameters; // Get an ImageCodecInfo object that represents the JPEG codec. myImageCodecInfo = GetEncoderInfo("image/jpeg"); // Create an Encoder object based on the GUID // for the Quality parameter category. myEncoder = System.Drawing.Imaging.Encoder.Quality; // Create an EncoderParameters object. // An EncoderParameters object has an array of EncoderParameter // objects. In this case, there is only one // EncoderParameter object in the array. myEncoderParameters = new EncoderParameters(1); // Save the bitmap as a JPEG file with 给定的 quality level myEncoderParameter = new EncoderParameter(myEncoder, level); myEncoderParameters.Param[0] = myEncoderParameter; srcBitmap.Save(destStream, myImageCodecInfo, myEncoderParameters); } /// <summary> /// 图片压缩(降低质量以减小文件的大小) /// </summary> /// <param name="srcBitMap">传入的Bitmap对象</param> /// <param name="destFile">压缩后的图片保存路径</param> /// <param name="level">压缩等级,0到100,0 最差质量,100 最佳</param> public void Compress(Bitmap srcBitMap, string destFile, long level) { Stream s = new FileStream(destFile, FileMode.Create); Compress(srcBitMap, s, level); s.Close(); } public string GetRequestValue(string key) { try { return HttpContext.Current.Request[key].ToString(); } catch (global::System.Exception) { return string.Empty; } } #region 字母随机数 /// <summary> /// 字母随机数 /// </summary> /// <param name="n">生成长度</param> /// <returns></returns> public static string RandLetter(int n) { char[] arrChar = new char[]{ 'a','b','d','c','e','f','g','h','i','j','k','l','m','n','p','r','q','s','t','u','v','w','z','y','x', '_', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','Q','P','R','T','S','V','U','W','X','Y','Z' }; StringBuilder num = new StringBuilder(); Random rnd = new Random(DateTime.Now.Millisecond); for (int i = 0; i < n; i++) { num.Append(arrChar[rnd.Next(0, arrChar.Length)].ToString()); } return num.ToString(); } #endregion /// <summary> /// 字符串是否为空 /// </summary> /// <param name="str"></param> /// <returns></returns> public bool StrEmpty(string str) { return string.IsNullOrEmpty(str); } public bool IsReusable { get { return false; } } } }