收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 

交流首页 » .NET »ASP.NET开发中如何解决多尺寸图片缩略图问题?  XML
发表人 内容
玫瑰情书
[头像]

交流经验:
总积分:380
级别:普通会员
注册时间: 2014-05-09
文章: 4
离线

在网站开发过程中,大家都是如何解决多尺寸图片缩略图问题的呢?犹为典型的是电商网站,据了解,淘宝的图片缩略图是直接存储多张缩略图的方式,以满足各种情况下使用,因为它有牛X的开源+自主开发的海量图片存储架构作支撑。但是,我们在做网站时,并不可能直接搬牛X的架构过来,就可以达到预期的效果,况且各种成本投入也是有限的。所以一般性能优化的原则大都是这样:先考虑软件的优化,再考虑硬件的升级,当然土豪客户则除外。
很多网站可能没有对图片进行缩略图处理,上传时图片可能几百KB,在页面也是直接加载几百KB的图片大小,这样极为占用带宽,影响网站加载速度。也有很多网站的做法可能也是直接根据前端页面所需求图片的尺寸,在上传时就处理生成相应尺寸的缩略图,但如果前端页面布局进行调整时,可能就得调整缩略图生成的尺寸,之前生成的图片也有可能需要重新生成。之前我在一个网站项目时就遇到这样的问题,经过一系列地验证,最终是采用动态缩略图技术解决的,现在北风网整理出来给大家分享分享。
其实,原理很简单,通过高性能的图片压缩算法,在一般处理程序(HttpHandler)对图片进行压缩处理,图片路径则直接指向HttpHandler,将图片路径、需要压缩的宽高等参数传进去,实现动态压缩。
在网站目录下新建 ResizeImage.ashx 文件,代码如下:


java代码:
using System;
using System.Collecti.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Drawing.Imaging;
using System.Drawing;
namespace www.ideek.cn
{
/// <summary>
/// 动态缩略图处理程序
/// 调用示例: <img runat="server" src="~/ResizeImage.ashx?src=/Upload/20140428/www_ideek_cn.jpg&width=128&height=128" />
/// </summary>
public class ResizeImageHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Respe.ContentType = "text/plain";
string fileName = context.Server.UrlDecode(context.Request["src"]);
if (string.IsNullOrEmpty(fileName))
{
context.Respe.Write("缺少参数src.");
return;
}
fileName = Server.MapPath("~/" + fileName);
Stream fileStream = null;
try
{
string wStr = context.Request["width"];
string hStr = context.Request["height"];
int width = 0, height = 0;
if (!string.IsNullOrEmpty(wStr) && !string.IsNullOrEmpty(hStr))
{
int.TryParse(wStr, out width);
int.TryParse(hStr, out height);
}
FileInfo fi = new FileInfo(fileName);
if (!fi.Exists)
{
context.Respe.Write("图片不存在.");
return;
}
string contentType = getContentType(fi.Extension);
context.Respe.ContentType = contentType;
//只能处理jpg及png图片格式,没有宽高参数不进行缩放处理
if (width > 0 && height > 0 && (contentType.Contains("jpeg") || contentType.Contains("png")))
{
Image image = Image.FromFile(fi.FullName);
int sWidth = image.Width, sHeight = image.Height;
int nWidth = 0, nHeight = 0;
if (sWidth > width || sHeight > height)
{
if (((double)sWidth / (double)sHeight) > ((double)width / (double)height))
{
//以宽度为基准缩小
if (sWidth > width)
{
nWidth = width;
nHeight = (int)(width * sHeight / (double)sWidth);
}
else
{
nWidth = sWidth;
nHeight = sHeight;
}
}
else
{
//以高度为基准缩小
if (sHeight > height)
{
nWidth = (int)(height * sWidth / (double)sHeight);
nHeight = height;
}
else
{
nWidth = sWidth;
nHeight = sHeight;
}
}
Bitmap bitmap = new Bitmap(nWidth, nHeight, PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.Clear(Color.White);
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; //平滑处理
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; //缩放质量
graphics.DrawImage(image, new Rectangle(0, 0, nWidth, nHeight));
image.Dispose();
EncoderParameters parameters = new EncoderParameters(1);
parameters.Param[0] = new EncoderParameter(Encoder.Quality, ((long)80)); //图片质量参数
fileStream = new MemoryStream();
bitmap.Save(fileStream, GetImageCodecInfo(contentType), parameters);
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, GetImageCodecInfo(contentType), parameters);
context.Respe.OutputStream.Write(ms.GetBuffer(), 0, (int)ms.Length);
}
parameters.Dispose();
bitmap.Dispose();
return;
}
if (image != null)
image.Dispose();
}
else
{
fileStream = new FileStream(fi.FullName, FileMode.Open);
byte[] bytes = new byte[(int)fileStream.Length];
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Close();
context.Respe.BinaryWrite(bytes);
}
}
catch (Exception ex)
{
context.Respe.Write(ex.Message);
}
finally
{
if (fileStream != null)
{
fileStream.Close();
fileStream.Dispose();
}
}
System.GC.Collect();
}
/// <summary>
/// 获取文件下载类型
/// </summary>
/// <param name="extension"></param>
/// <returns></returns>
private string getContentType(string extension)
{
string ct = string.Empty;
switch (extension.ToLower())
{
case ".jpg":
ct = "image/jpeg";
break;
case ".png":
ct = "image/png";
break;
case ".gif":
ct = "image/gif";
break;
case ".bmp":
ct = "application/x-bmp";
break;
default:
ct = "image/jpeg";
break;
}
return ct;
}
//获得包含有关内置图像编码解&码&器的信息的ImageCodecInfo 对象.
private ImageCodecInfo GetImageCodecInfo(string contentType)
{
ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegICI = null;
for (int x = 0; x < arrayICI.Length; x++)
{
if (arrayICI[x].MimeType.Equals(contentType))
{
jpegICI = arrayICI[x];
//设置JPEG编码
break;
}
}
return jpegICI;
}
public bool IsReusable
{
get
{
return false;
}
}
}
}

图片压缩算法中,有几个参数可以根据自己的需求进行调整,比如:SmoothingMode、InterpolationMode、Encoder.Quality,反正图片的大小与图片质量成正比,也跟性能成反比,具体参数用法,请移步MSDN查看,因此大家根据实际需求进行取舍了。
在页面需要调用地方,将img的src设置为ResizeImage.ashx,这跟图片验证码处理方式一样,如:


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

这样,一张图片可以在网站任意地方使用,图片经过压缩后传输,通过Google或Firefox浏览器开发者工具可以很明显地看出图片大小效果和加载速度都有非常明显的提升。
当然,可能很多人会问频繁的计算对服务器会产生性能影响,所以在实际使用过程中,可以根据自己的需求采用一些手段进行规避,比如引入缓存机制等,这些优化将会在后续文章中讲解。

 

转自:http://bbs.ibeifeng.com/read-htm-tid-65487.html


推广链接
精品视频课程推荐

Java数据结构和算法精讲版
本课程专注于数据结构和算法的内容,使用Java来进行代码示例,不空洞的讲解概念和理论,重点放在代码的实现和示例上。 从零开始、全面系统、成体系的讲解数据结构和基本算法,循序渐进的讲述构建软件系统所常见的数据结构和算法。

深入浅出学Shrio视频教程
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术 技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容

Ajax+JSON基础实战视频教程
数据校验、Javascript模拟多线程、下拉列表联动、操作XML、AJAX结合JSON的操作、Json-lib的使用

Weblogic实战视频教程
WebLogic基础知识:WebLogic基本概念、正确安装WebLogic、建域、应用部署于JDBC选择、对WebLogic的监控和日志查看、集群的高可用性;课程目标:彻底掌握WebLogic的基本概念,在理解基本概念的基础上做到正确的安装WebLogic,根据不同的需求创建域,合理选择应用部署和JDBC配置。熟练掌握WebLogic的console监控,了解各种性能和运行指标,以及对监控结果的分析,运用集群的高可用性,对集群架设。

最新jbpm4工作流开发实战视频教程
从零到精通jBPM的开发知识;理解工作流的理论、掌握自行开发工作流的思路、系统学习使用jBPM来实现工作流应用、掌握jBPM和Web项目的结合、掌握一些实际开发中典型的业务实现(会签、委托等)



个性签名:http://www.ibeifeng.com/
 
交流首页 » .NET
前往:   

关于我们 | 联系我们 | 用户协议 | 私塾在线服务协议 | 版权声明 | 隐私保护

版权所有 Copyright(C)2009-2012 私塾在线学习网