网站上可能会有很多图片,比如产品图片等,而且他们可能大小不一,宽度和高度也不一定一样,有的很大有的很小。如果放在一张网页上,可能会破坏版面,但是如果强制让他们按照指定的宽度和高度显示,因为比例不同还会出现变形,显示效果很糟糕,还有最大的缺点是,文件尺寸丝毫没有变化,当图片很大的时候,用户想要看到图片,必须经过漫长等待下载图片,怎么办呢? 好,这里设计到了缩略图,就像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 Language="vb" AutoEventWireup="false" Codebehind="GetThumbnail.aspx.vb" Inherits="_51use.GetThumbnail"%>
这一句Page指令仅仅是告诉服务器,这个文件的隐藏类是_51use.GetThumbnail,而如果我们都不作任何操作的话,这个文件最终输出时空的。 接下来看一下他的隐藏类是如何写的,在这里我们使用的是B语言:
程序代码:
源代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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 MeiYuan 15 { 16 /**/ /// <summary> 17 /// GetThumbnail的摘要说明。 18 /// </summary> 19 public class GetThumbnail:System.Web.UI.Page 20 { 21 22 private void Page_Load( object sender,System.EventArgse) 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 ColorConvertercv= new ColorConverter(); 32 ColorbgColor= (Color)cv.ConvertFromString( " # " + bgColorString); 33 34 System.Drawing.Imageimg= System.Drawing.Image.FromFile(originalFileName); 35 36 System.Drawing.Imaging.ImageFormatthisFormat= img.RawFormat; 37 38 System.Drawing.SizenewSize= this .GetNewSize(thumbnailWidth,thumbnailHeight,img.Width,img.Height); 39 40 System.Drawing.BitmapoutBmp= new Bitmap(thumbnailWidth,thumbnailHeight); 41 42 System.Drawing.Graphicsg= 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 else 61 { 62 Response.ContentType= " image/jpeg " ; 63 }64 65 66 // 设置压缩质量 67 System.Drawing.Imaging.EncoderParametersencoderParams = new EncoderParameters(); 68 69 System.Drawing.Imaging.EncoderParameterencoderParam= 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.ImageCodecInfojpegICI= 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 else 93 { 94 outBmp.Save(Response.OutputStream,thisFormat);95 }96 97 98 99 }100 101 Web窗体设计器生成的代码 #region Web窗体设计器生成的代码 102 override protected void OnInit(EventArgse) 103 { 104 // 105 // CODEGEN:该调用是ASP.NETWeb窗体设计器所必需的。 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 #endregion 120 121 System.Drawing.SizeGetNewSize(int maxWidth, int maxHeight, int width, int height) 122 { 123 Doublew= 0.0 ; 124 Doubleh= 0.0 ; 125 Doublesw= Convert.ToDouble(width); 126 Doublesh= Convert.ToDouble(height); 127 Doublemw= Convert.ToDouble(maxWidth); 128 Doublemh= 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 else 141 { 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
网页中使用方法
调用示例
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->1 < Ahref = ' ProductDetail.aspx?ProductID=<%#DataBinder.Eval(Container,"DataItem.ProductID")%> ' target = _blank > < IMGheight = 80 src = ' GetThumbnail.aspx?fn=<%#Server.UrlEncode(DataBinder.Eval(Container,"DataItem.ImageUrl").ToString())%>&tw=80&th=80&bg=FFF3F7 ' width = 80 border = 0 > </ A >