网站上可能会有很多图片,比如产品图片等,而且他们可能大小不一,宽度和高度也不一定一样,有的很大有的很小。如果放在一张网页上,可能会破坏版面,但是如果强制让他们按照指定的宽度和高度显示,因为比例不同还会出现变形,显示效果很糟糕,还有最大的缺点是,文件尺寸丝毫没有变化,当图片很大的时候,用户想要看到图片,必须经过漫长等待下载图片,怎么办呢?
好,这里设计到了缩略图,就像Windows中的缩略图查看一样,你所看到的是从原图按照1:1比例缩小的图片,而且满足规定在指定宽度和高度的范围内显示(如果图片填不满,就用空白)。缩略图不是原图,而是利用原图实时按照指定大小生成的,他的好处就是你可以充分控制缩略图的质量,宽度高度,文件大小也在合理的范围内,省去漫长等待。
本文将讨论如何生成缩略图,举一反三,又可以派生许多用处,比如,自己写一个验证码控件等。
1、理解对图片的请求和流
一般来说,我们用http://xxx/a.aspx对a.aspx网页请求。ASP.NET处理了网页以后,就把该网页的内容发送回浏览器。a.aspx的内容一般是含有超文本标记的文本文件流,这是谁都不会怀疑的。但是a.aspx不但能够返回这种非常平常的网页文本外,把它广义开来,它其实可以放回任何类型的流数据。而,我们只需要对Response对象进行操作即可改变输出流的内容。
把图像文件看作是一个二进制流,我们试图从一个图像文件创建了他的流对象,并且将流写入到Response.OutputStream中,这样图像文件就被发给了请求的浏览器。但是浏览器还必须要识别出这是一个图像文件,因此,在发送这个流之前,将Response.ContentType更改成这种图像文件的MIME类型。浏览器在收到这个流之后,调用相关的应用程序,图像就被显示在了浏览器上。虽然实际地址还是aspx结尾。
这样我们就能很好理解怎么去向用户发送标记。例如,在一张普通的网页中写标记img标记,使他的src指向a.aspx。浏览器在得到这张网页后,会处理img标记的内容,并向a.aspx发出请求,这是a.aspx作为图像流返回,浏览器就将图片显示出来。
2、生成缩略图
有了上述技术基础,我们可以建立这样一个空的aspx网页,他通过接受传入的参数,生成缩略图的流,发送回浏览器。
我们创建一个名叫GetThumbnail.aspx的文件,内容如下:
这一句Page指令仅仅是告诉服务器,这个文件的隐藏类是_51use.GetThumbnail,而如果我们都不作任何操作的话,这个文件最终输出时空的。
接下来看一下他的隐藏类是如何写的,在这里我们使用的是B语言:
1
using System;2
using System.Collections;3
using System.ComponentModel;4
using System.Data;5
using System.Drawing;6
using System.Drawing.Drawing2D;7
using System.Drawing.Imaging;8
using System.Web;9
using System.Web.SessionState;10
using System.Web.UI;11
using System.Web.UI.WebControls;12
using System.Web.UI.HtmlControls;13

14
namespace MeiYuan15
{16
/// <summary>17
/// GetThumbnail 的摘要说明。18
/// </summary>19
public class GetThumbnail : System.Web.UI.Page20
{21
22
private void Page_Load(object sender, System.EventArgs e)23
{24
Response.Clear();25

26
string originalFileName = Server.MapPath(Request.QueryString["fn"]);27
int thumbnailWidth = Convert.ToInt16(Request.QueryString["tw"]);28
int thumbnailHeight = Convert.ToInt16(Request.QueryString["th"]);29
string bgColorString = Convert.ToString(Request.QueryString["bg"]);30
31
ColorConverter cv = new ColorConverter();32
Color bgColor = (Color)cv.ConvertFromString("#"+bgColorString);33
34
System.Drawing.Image img = System.Drawing.Image.FromFile(originalFileName);35

36
System.Drawing.Imaging.ImageFormat thisFormat = img.RawFormat;37

38
System.Drawing.Size newSize = this.GetNewSize(thumbnailWidth, thumbnailHeight, img.Width, img.Height);39

40
System.Drawing.Bitmap outBmp = new Bitmap(thumbnailWidth, thumbnailHeight);41
42
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(outBmp);43
44
//设置画布的描绘质量45
g.CompositingQuality = CompositingQuality.HighQuality;46
g.SmoothingMode = SmoothingMode.HighQuality;47
g.InterpolationMode = InterpolationMode.HighQualityBicubic;48
//g.Clear(System.Drawing.Color.FromArgb(255, 249, 255, 240));49
g.Clear(bgColor);50
g.DrawImage(img, new Rectangle((thumbnailWidth - newSize.Width)/2,51
(thumbnailHeight - newSize.Height)/2,52
newSize.Width, newSize.Height),53
0, 0, img.Width, img.Height, GraphicsUnit.Pixel);54
g.Dispose();55
56
if(thisFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif))57
{58
Response.ContentType = "image/gif";59
}60
else61
{62
Response.ContentType = "image/jpeg";63
}64
65
66
//设置压缩质量67
System.Drawing.Imaging.EncoderParameters encoderParams = new EncoderParameters();68
69
System.Drawing.Imaging.EncoderParameter encoderParam =70
new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, new long[] {100});71
encoderParams.Param[0] = encoderParam;72
73
74

75
//获得包含有关内置图像编码解码器的信息的ImageCodecInfo 对象。76
System.Drawing.Imaging.ImageCodecInfo[] arrayICI = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();77
System.Drawing.Imaging.ImageCodecInfo jpegICI = null;78
79
for(int fwd = 0; fwd < arrayICI.Length; fwd++)80
{81
if(arrayICI[fwd].FormatDescription.Equals("JPEG"))82
{83
jpegICI = arrayICI[fwd];84
break;85
}86
}87
88
if(jpegICI == null)89
{90
outBmp.Save(Response.OutputStream, jpegICI, encoderParams);91
}92
else93
{94
outBmp.Save(Response.OutputStream, thisFormat);95
}96

97
98

99
}100

101
#region Web 窗体设计器生成的代码102
override protected void OnInit(EventArgs e)103
{104
//105
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。106
//107
InitializeComponent();108
base.OnInit(e);109
}110
111
/// <summary>112
/// 设计器支持所需的方法 - 不要使用代码编辑器修改113
/// 此方法的内容。114
/// </summary>115
private void InitializeComponent()116
{ 117
this.Load += new System.EventHandler(this.Page_Load);118
}119
#endregion120
121
System.Drawing.Size GetNewSize(int maxWidth, int maxHeight , int width , int height)122
{123
Double w = 0.0;124
Double h = 0.0;125
Double sw = Convert.ToDouble(width);126
Double sh = Convert.ToDouble(height);127
Double mw = Convert.ToDouble(maxWidth);128
Double mh = Convert.ToDouble(maxHeight);129
130
if(sw < mw && sh < mh)131
{132
w = sw;133
h = sh;134
}135
else if((sw / sh) > (mw / mh))136
{137
w = maxWidth;138
h = (w*sh)/sw;139
}140
else141
{142
h = maxHeight;143
w = (h*sw)/sh;144
}145
return new System.Drawing.Size(Convert.ToInt32(w), Convert.ToInt32(h));146
}147
148
149
}150
}151
网页中使用方法
1
<A href='ProductDetail.aspx?ProductID=<%# DataBinder.Eval(Container, "DataItem.ProductID")%>' target=_blank><IMG height=80 src='GetThumbnail.aspx?fn=<%# Server.UrlEncode(DataBinder.Eval(Container, "DataItem.ImageUrl").ToString())%>&tw=80&th=80&bg=FFF3F7' width=80 border=0>
</A>
本文介绍了一种在ASP.NET中生成图片缩略图的方法,通过接收原图路径、目标宽度和高度等参数,动态生成符合要求的缩略图并发送给浏览器。文中详细解释了如何利用Response对象和图像处理技术实现此功能。


2916

被折叠的 条评论
为什么被折叠?



