网站性能优化:动态缩略图技术实现思路

  在网站开发过程中,大家都是如何解决多尺寸图片缩略图问题的呢?犹为典型的是电商网站,据了解,淘宝的图片缩略图是直接存储多张缩略图的方式,以满足各种情况下使用,因为它有牛逼的开源+自主开发的海量图片存储架构作支撑。但是,我们在做网站时,并不可能直接搬牛逼的架构过来,就可以达到预期的效果,况且各种成本投入也是有限的。所以一般性能优化的原则大都是这样:先考虑软件的优化,再考虑硬件的升级,当然土豪客户则除外。

  很多网站可能没有对图片进行缩略图处理,上传时图片可能几百KB,在页面也是直接加载几百KB的图片大小,这样极为占用带宽,影响网站加载速度。也有很多网站的做法可能也是直接根据前端页面所需求图片的尺寸,在上传时就处理生成相应尺寸的缩略图,但如果前端页面布局进行调整时,可能就得调整缩略图生成的尺寸,之前生成的图片也有可能需要重新生成。之前我在一个网站项目时就遇到这样的问题,经过一系列地验证,最终是采用动态缩略图技术解决的,现在整理出来给大家分享分享。

  其实,原理很简单,通过高性能的图片压缩算法,在一般处理程序(HttpHandler)对图片进行压缩处理,图片路径则直接指向HttpHandler,将图片路径、需要压缩的宽高等参数传进去,实现动态压缩。

  在网站目录下新建 ResizeImage.ashx 文件,代码如下:


  1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.IO;
6 using System.Drawing.Imaging;
7 using System.Drawing;
8
9 namespace www.ideek.cn
10 {
11 /// <summary>
12 /// 动态缩略图处理程序
13 /// 调用示例: <img runat="server" src="~/ResizeImage.ashx?src=/Upload/20140428/www_ideek_cn.jpg&width=128&height=128" />
14 /// </summary>
15 public class ResizeImageHandler : IHttpHandler
16 {
17 public void ProcessRequest(HttpContext context)
18 {
19 context.Response.ContentType = "text/plain";
20 string fileName = context.Server.UrlDecode(context.Request["src"]);
21 if (string.IsNullOrEmpty(fileName))
22 {
23 context.Response.Write("缺少参数src.");
24 return;
25 }
26 fileName = Server.MapPath("~/" + fileName);
27
28 Stream fileStream = null;
29 try
30 {
31 string wStr = context.Request["width"];
32 string hStr = context.Request["height"];
33 int width = 0, height = 0;
34 if (!string.IsNullOrEmpty(wStr) && !string.IsNullOrEmpty(hStr))
35 {
36 int.TryParse(wStr, out width);
37 int.TryParse(hStr, out height);
38 }
39
40 FileInfo fi = new FileInfo(fileName);
41 if (!fi.Exists)
42 {
43 context.Response.Write("图片不存在.");
44 return;
45 }
46 string contentType = getContentType(fi.Extension);
47 context.Response.ContentType = contentType;
48
49 //只能处理jpg及png图片格式,没有宽高参数不进行缩放处理
50 if (width > 0 && height > 0 && (contentType.Contains("jpeg") || contentType.Contains("png")))
51 {
52 Image image = Image.FromFile(fi.FullName);
53 int sWidth = image.Width, sHeight = image.Height;
54 int nWidth = 0, nHeight = 0;
55 if (sWidth > width || sHeight > height)
56 {
57 if (((double)sWidth / (double)sHeight) > ((double)width / (double)height))
58 {
59 //以宽度为基准缩小
60 if (sWidth > width)
61 {
62 nWidth = width;
63 nHeight = (int)(width * sHeight / (double)sWidth);
64 }
65 else
66 {
67 nWidth = sWidth;
68 nHeight = sHeight;
69 }
70 }
71 else
72 {
73 //以高度为基准缩小
74 if (sHeight > height)
75 {
76 nWidth = (int)(height * sWidth / (double)sHeight);
77 nHeight = height;
78 }
79 else
80 {
81 nWidth = sWidth;
82 nHeight = sHeight;
83 }
84 }
85
86 Bitmap bitmap = new Bitmap(nWidth, nHeight, PixelFormat.Format32bppArgb);
87 Graphics graphics = Graphics.FromImage(bitmap);
88 graphics.Clear(Color.White);
89 graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; //平滑处理
90 graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; //缩放质量
91 graphics.DrawImage(image, new Rectangle(0, 0, nWidth, nHeight));
92 image.Dispose();
93
94 EncoderParameters parameters = new EncoderParameters(1);
95 parameters.Param[0] = new EncoderParameter(Encoder.Quality, ((long)80)); //图片质量参数
96
97 fileStream = new MemoryStream();
98 bitmap.Save(fileStream, GetImageCodecInfo(contentType), parameters);
99 using (MemoryStream ms = new MemoryStream())
100 {
101 bitmap.Save(ms, GetImageCodecInfo(contentType), parameters);
102 context.Response.OutputStream.Write(ms.GetBuffer(), 0, (int)ms.Length);
103 }
104 parameters.Dispose();
105 bitmap.Dispose();
106 return;
107 }
108 if (image != null)
109 image.Dispose();
110 }
111 else
112 {
113 fileStream = new FileStream(fi.FullName, FileMode.Open);
114 byte[] bytes = new byte[(int)fileStream.Length];
115 fileStream.Read(bytes, 0, bytes.Length);
116 fileStream.Close();
117 context.Response.BinaryWrite(bytes);
118 }
119 }
120 catch (Exception ex)
121 {
122 context.Response.Write(ex.Message);
123 }
124 finally
125 {
126 if (fileStream != null)
127 {
128 fileStream.Close();
129 fileStream.Dispose();
130 }
131 }
132 System.GC.Collect();
133 }
134
135
136 /// <summary>
137 /// 获取文件下载类型
138 /// </summary>
139 /// <param name="extension"></param>
140 /// <returns></returns>
141 private string getContentType(string extension)
142 {
143 string ct = string.Empty;
144 switch (extension.ToLower())
145 {
146 case ".jpg":
147 ct = "image/jpeg";
148 break;
149 case ".png":
150 ct = "image/png";
151 break;
152 case ".gif":
153 ct = "image/gif";
154 break;
155 case ".bmp":
156 ct = "application/x-bmp";
157 break;
158 default:
159 ct = "image/jpeg";
160 break;
161 }
162 return ct;
163 }
164
165 //获得包含有关内置图像编码解码器的信息的ImageCodecInfo 对象.
166 private ImageCodecInfo GetImageCodecInfo(string contentType)
167 {
168 ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
169 ImageCodecInfo jpegICI = null;
170 for (int x = 0; x < arrayICI.Length; x++)
171 {
172 if (arrayICI[x].MimeType.Equals(contentType))
173 {
174 jpegICI = arrayICI[x];
175 //设置JPEG编码
176 break;
177 }
178 }
179 return jpegICI;
180 }
181
182 public bool IsReusable
183 {
184 get
185 {
186 return false;
187 }
188 }
189 }
190 }

  图片压缩算法中,有几个参数可以根据自己的需求进行调整,比如:SmoothingMode、InterpolationMode、Encoder.Quality,反正图片的大小与图片质量成正比,也跟性能成反比,具体参数用法,请移步MSDN查看,因此大家根据实际需求进行取舍了。

  在页面需要调用地方,将img的src设置为ResizeImage.ashx,这跟图片验证码处理方式一样,如:

1 <img runat="server"
src="~/ResizeImage.ashx?src=/Upload/20140428/www_ideek_cn.jpg&width=128&height=128"
/>

  这样,一张图片可以在网站任意地方使用,图片经过压缩后传输,通过Google或Firefox浏览器开发者工具可以很明显地看出图片大小效果和加载速度都有非常明显的提升。

  当然,可能很多人会问频繁的计算对服务器会产生性能影响,所以在实际使用过程中,可以根据自己的需求采用一些手段进行规避,比如引入缓存机制等,这些优化将会在后续文章中讲解。

网站性能优化:动态缩略图技术实现思路,布布扣,bubuko.com

时间: 2024-10-14 13:49:37

网站性能优化:动态缩略图技术实现思路的相关文章

Yahoo! 35条网站性能优化建议

Yahoo! 35条网站性能优化建议 分类: 网站性能优化2014-03-08 17:18 212人阅读 评论(0) 收藏 举报 网站性能优化 Yahoo!的 Exceptional Performance团队为改善 Web性能带来最佳实践.他们为此进行了一系列的实验.开发了各种工具.写了大量的文章和博客并在各种会议上参与探讨.最佳实践的核心就是旨在提高网站性能.原版猛戳:Best Practices for Speeding Up Your Web Site, Excetional Perfo

网站性能优化

之前在做电商网站的时候,曾经因为网站图片太多,加载过慢而不得不提高服务器性能,但阿里云服务器提升性能较贵,便去找了找关于网站性能优化的知识,没想到的确省了一些钱,性能有所好转.最近公司的项目又再次涉及到性能优化问题,总结了下之前经历的项目经验,得出以下几点优化思路: 1.从请求入手,找到最慢的一个 就好像木桶原理一样,找到最短的一块进行弥补.性能优化也一样,找到最慢的那部分请求进行优化.一般可以分为图片.css\js文件.后台请求等几方面. 通过对请求进行分析找到最慢的一个进行优化 2.图片优化

[转载]网站前端性能优化之javascript和css——网站性能优化

之前看过Yahoo团队写的一篇关于网站性能优化的文章,文章是2010年左右写的,虽然有点老,但是很多方面还是很有借鉴意义的.关于css的性能优化,他提到了如下几点: CSS性能优化 1.把样式表置于顶部 现把样式表放到文档的< head />内部似乎会加快页面的下载速度.这是因为把样式表放到< head />内会使页面有步骤的加载显示. 注重性能的前端服务器往往希望页面有秩序地加载.同时,我们也希望浏览器把已经接收到内容尽可能显示出来.这对于拥有较多内容的页面和网速较慢的用户来说特

【转】Yahoo!团队:网站性能优化的35条黄金守则

Yahoo!的 Exceptional Performance团队为改善 Web性能带来最佳实践.他们为此进行了一系列的实验.开发了各种工具.写了大量的文章和博客并在各种会议上参与探讨.最佳实践的核心就是旨在提高网站性能. 原版猛戳:https://developer.yahoo.com/performance/rules.html,本文转自:http://blog.csdn.net/xianghongai/article/details/9241549 Excetional Performan

Yahoo团队经验:网站性能优化的34条黄金法则

Yahoo团队总结的关于网站性能优化的经验,非常有参考价值.英文原文:http://developer.yahoo.com/performance/rules.html 1.尽量减少HTTP请求次数 终端用户响应的时间中,有80%用于下载各项内容.这部分时间包括下载页面中的图像.样式表.脚本.Flash等.通过减少页面中的元素可以减少 HTTP请求的次数.这是提高网页速度的关键步骤.减少页面组件的方法其实就是简化页面设计.那么有没有一种方法既能保持页面内容的丰富性又能达到加快响应时间的目的呢?这

mysql分解连接的总结(来自于高性能MySQL以及自己网站性能优化)

许多高性能的站点都用了"分解连接"技术,也就是把单个多表连接查询改成多个但表查询,然后在程序中合并数据,比如: select a.*,b.* from A a join B b on a.id = b.id 可以替换为: select a.* from A; select b.* from B; 然后再把数据通过程序合并. 可能有些人认为这太浪费了,把一个查询语句变成两条查询语句或者更多的查询语句了,如果哪位猿类这样想了,那你就应该继续往下看了. 将连接查询重构为多表查询,总体有以下性

如何进行网站性能优化

如何进行网站性能优化 雅虎Best Practices for Speeding Up Your Web Site: content方面 减少HTTP请求:合并文件.CSS精灵.inline Image 减少DNS查询:DNS查询完成之前浏览器不能从这个主机下载任何任何文件.方法:DNS缓存.将资源分布到恰当数量的主机名,平衡并行下载和DNS查询 避免重定向:多余的中间访问 使Ajax可缓存 非必须组件延迟加载 未来所需组件预加载 减少DOM元素数量 将资源放到不同的域下:浏览器同时从一个域下载

网站性能优化你需知道的东西

本文提到的网站性能指网站的响应速度,这也符合绝大部分人对于网站性能的理解:访问快速的网站性能好,反之,访问速度越慢,则网站性能越差.本文总结的优化方法是宏观的工程层面的方法,并不包含微观的语言语法层面的方法,例如,JS.CSS的语法优化,这一部分同样影响网站的性能,但语言语法层面的优化更多的是取决于开发人员的编程水平. 什么样的网站响应速度快呢?其实很容易想到,网站加载资源的速度越快,网站响应速度越快:网站需要加载的资源越少,网站响应速度越快.这就分别对应网站性能优化的两大方向:资源缓存.资源合

网站性能优化(一)

前段时间面试时,面试官问了一个问题:"网站性能优化有什么方法",我当时的第一反应就是减少图片加载,把图片直接转成base64,然后直接写到css中,这样能减少从后台拿数据的次数,然后我直接说出了我的想法.面试官问还有没有其他方法,我就一脸茫然了.回来之后我赶快看了<高性能网站优化指南>,里面介绍了不少有用的方法,有前端的也有后端,有些我们平时开发的时候一直在用,但是没有觉得能提高网站的性能,有些就从来没有想到过.下面我主要介绍一下这本书里面的前端性能优化方法吧~ 1.减少h