网站上可能会有很多图片,比如产品图片等,而且他们可能大小不一,宽度和高度也不一定一样,有的很大有的很小。如果放在一张网页上,可能会破坏版面,但是如果强制让他们按照指定的宽度和高度显示,因为比例不同还会出现变形,显示效果很糟糕,还有最大的缺点是,文件尺寸丝毫没有变化,当图片很大的时候,用户想要看到图片,必须经过漫长等待下载图片,怎么办呢?

好,这里涉及到了缩略图,就像Windows中的缩略图查看一样,你所看到的是从原图按照1:1比例缩小的图片,而且满足规定在指定宽度和高度的范围内显示(如果图片填不满,就用空白)。缩略图不是原图,而是利用原图实时按照指定大小生成的,他的好处就是你可以充分控制缩略图的质量,宽度高度,文件大小也在合理的范围内,省去漫长等待。

本文将讨论如何生成缩略图,举一反三,又可以派生许多用处,比如,自己写一个验证码控件等。

1、理解对图片的请求和流
一般来说,我们用http://xxx/a.aspx对a.aspx网页请求。ASP.NET处理了网页以后,就把该网页的内容发送回浏览器。a.aspx的内容一般是含有超文本标记的文本文件流(Response.ContentType即输出流的 HTTP MIME 类型,默认值是“text/html”),这是谁都不会怀疑的。但是a.aspx不但能够返回这种平常的网页文本外,把它广义开来,它其实可以返回任何类型的流数据。而,我们只需要对Response对象进行操作即可改变输出流的内容。
把图像文件看作是一个二进制流,我们试图从一个图像文件创建了他的流对象,并且将流写入到Response.OutputStream中,这样图像文件就被发给了请求的浏览器。但是浏览器还必须要识别出这是一个图像文件,因此,在发送这个流之前,将Response.ContentType更改成这种图像文件的MIME类型。浏览器在收到这个流之后,调用相关的应用程序,图像就被显示在了浏览器上。虽然实际地址还是aspx结尾。
这样我们就能很好理解怎么去向用户发送标记。例如,在一张普通的网页中写img标签,使它的src指向a.aspx。浏览器在得到这张网页后,会处理img标签的内容,并向a.aspx发出请求,这时a.aspx作为图像流返回,浏览器就将图片显示出来。

2、生成缩略图

新建webform页面,它通过接受传入的参数,生成缩略图的流,发送回浏览器。cs代码如下:

using System;
using System.Drawing;
using System.Drawing.Imaging; namespace Demo.Web
{
public partial class GetThumbnail : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Clear(); string originalFileName =Server.MapPath( Request.QueryString["imgSrc"]);
int thumbnailWidth = Convert.ToInt32(Request.QueryString["width"]);
int thumbnailHeight = Convert.ToInt32(Request.QueryString["height"]); System.Drawing.Image img = System.Drawing.Image.FromFile(originalFileName);
var thisFormat = img.RawFormat;
System.Drawing.Size newSize = GetNewSize(thumbnailWidth, thumbnailHeight, img.Width, img.Height);
var outBmp = new System.Drawing.Bitmap(thumbnailWidth, thumbnailHeight);
var g = System.Drawing.Graphics.FromImage(outBmp);
//设置画布的描绘质量
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.Clear(System.Drawing.Color.FromArgb(, , , ));//.Transparent);//.FromArgb(255, 249, 255, 240));
g.DrawImage(img, new Rectangle((thumbnailWidth - newSize.Width) / ,
(thumbnailHeight - newSize.Height) / ,
newSize.Width, newSize.Height), , , img.Width, img.Height, GraphicsUnit.Pixel);
g.Dispose(); if (thisFormat == System.Drawing.Imaging.ImageFormat.Gif)
{
Response.ContentType = "image/gif";
}
else
{
Response.ContentType = "image/jpeg";
} // 设置压缩质量
EncoderParameters encoderParams = new EncoderParameters();
long[] quality = new long[];
quality[] = ;
EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
encoderParams.Param[] = encoderParam; //获得包含有关内置图像编码解码器的信息的ImageCodecInfo 对象。
var arrayICI = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.ImageCodecInfo jpegICI = null;
for (int fwd = ; fwd < arrayICI.Length; fwd++)
{
if (arrayICI[fwd].FormatDescription.Equals("JPEG"))
{
jpegICI = arrayICI[fwd];
break;
}
} if (jpegICI != null)
outBmp.Save(Response.OutputStream, jpegICI, encoderParams);
else
outBmp.Save(Response.OutputStream, img.RawFormat); } private Size GetNewSize(int maxWidth, int maxHeight, int width, int height)
{
double w = 0.0;
double h = 0.0;
double sw = Convert.ToDouble(width);
double sh = Convert.ToDouble(height);
double mw = Convert.ToDouble(maxWidth);
double mh = Convert.ToDouble(maxHeight); if (sw < mw && sh < mh)
{
w = sw;
h = sh;
}
else if ((sw / sh) > (mw / mh))
{
w = maxWidth;
h = (w * sh) / sw;
}
else
{
h = maxHeight;
w = (h * sw) / sh;
}
return new System.Drawing.Size(Convert.ToInt32(w), Convert.ToInt32(h));
}
}
}

我们在Page_Load事件处理函数中,先获取要生成缩略图的原始文件的路径,和缩略图的宽度高度。
然后设置了一个子函数GetNewSize用以计算真正缩略图的大小(为什么还要计算阿?因为缩略图的宽高比和原始图片的宽高比不一样,缩小的图片要保证比例,按照比例缩小的原始图片,是按照约束在指定缩略图宽高范围内的原则,填充不满的地方使用背景色填补空白。另外,原图比缩略图小的话,我们就不做放大,而是按原图输出,所以计算是必须的)。

我们从原始图像创建了他的Image对象,并获得它的格式等信息,稍后用得到。

接下来新建一个BitMap对象,并由新的BitMap对象创建画板。设置画笔质量为高,交错模式为高质量立方式,这些的目的是使用最好的质量描绘缩略图,否则图片缩小后信息丢失图片失真就不好看了。接着,用指定的宽度和高度将原始图像的Image对象“画”在新的画板上。

修改Response.ContentType,这一步是告诉浏览器发送回的流的MIME类型,这个内容包含在HTTP Header中发送给浏览器。

图像画好了,现在我们要将其压缩一下,因为位图对象是很大的,不利于传输。因此下面的操作,我们设定一些高质量的压缩参数,根据获得的ICI(图像编码解码器信息),使用BitMap的Save方法将图片保存在Response.OutputStream流中。

这样在浏览器看来,对该网页的请求,相当于对一个图片文件的请求,只不过图片是实时生成的,只要传递参数合法有效,即可得到该图片的缩略图。

3、使用缩略图
使用缩略图就变得相对简单了,只需要在URL后附上参数imgSrc表示原始文件的位置(相对于根目录),width缩略图宽度,height缩略图高度,下列简单显示了在Repeater中使用的情景:

<img alt='' border="0" src='GetThumbnail.aspx?imgsrc=<%#Eval("ImgUrl") %>&width=300&height=300' />

下面就等着看看缩略图的效果:

后记
本文中所述的缩略图生成法,使用的是流的概念,和文件系统也不沾边,因此这种方式可以跳过对文件系统权限检查,百分之百正确运行。当然,也可以借助文件系统。另外,根据上面流输出的概念,举一反三,可以弄出很多用法,例如NeoDynamic的条形码控件,你会发现条形码图片的路径居然就是本页页面,他巧妙地将对本页的请求通过对几个特征参数的判定而转向生成图片流,从而达到了不添加任何页面,不借助文件系统的“神奇效果”,只需要一个DLL即可使用。
另外,很多人问生成验证码图片,也可以使用这样的思路,自己做一个这样的控件,或者网页。如果能做自定义控件更好。相信大家有这个能力。

ASP.NET将原始图片按照指定尺寸等比例缩放显示图片的更多相关文章

  1. ios 图片处理( 1.按比例缩放 2.指定宽度按比例缩放

    本文转载至 http://blog.sina.com.cn/s/blog_6f29e81f0101tat6.html //按比例缩放,size 是你要把图显示到 多大区域 CGSizeMake(300 ...

  2. jQuery实现等比例缩放大图片

      在布局页面时,有时会遇到大图片将页面容器“撑破”的情况,尤其是加载外链图片(通常是通过采集的外站的图片).那么本文将为您讲述使用jQuery如何按比例缩放大图片,让大图片自适应页面布局. 通常我们 ...

  3. jQuery实现等比例缩放大图片让大图片自适应页面布局

    通常我们处理缩略图是使用后台代码(PHP..net.Java等)根据大图片生成一定尺寸的缩略图,来供前台页面调用,当然也有使用前台javascript脚本将加载后的大图强行缩放,变成所谓的缩略图,这种 ...

  4. iOS开发小技巧--即时通讯项目:使用富文本在UILabel中显示图片和文字;使用富文本占位显示图片

    Label借助富文本显示图片 1.即时通讯项目中语音消息UI的实现,样式如图: 借助富文本在UILabel中显示图片和文字 // 1.创建一个可变的富文本 NSMutableAttributedStr ...

  5. 【js】【图片瀑布流】js瀑布流显示图片20180315

    js实现把图片用瀑布流显示,只需要“jquery-1.11.2.min.js”. js: //瀑布流显示图片 var WaterfallImg = { option: { maxWidth: 850, ...

  6. 纯JS实现图片预览与等比例缩放和居中

    最近做项目时有一个需求,广告位图片上传时要预览,并且要等比例缩放和居中.已经保存的广告位图片显示时也要等比例缩放和居中.我使用了下面的代码实现,不过可能有一些小问题. <!DOCTYPE HTM ...

  7. WPF通过鼠标滑轮缩放显示图片

    如果你使用WinForm比较难实现通过滚动鼠标滑轮来对图片进行缩放显示,那么,你应该考虑一下使用WPF,既然是下一代Windows客户端开发平台,明显是有一定优势的,不然,MS是吃饱了撑着.   首先 ...

  8. 关于springmvc 只能在index.jsp页面显示图片的处理办法jsp页面无法显示图片

    首先,已经配置好了mvc对静态资源的处理 只有index,jsp可以显示图片 其他页面同样的代码则不显示 后来折腾了半天,发现 index是static的父目录的级别文件 可以向下访问 但是其他的js ...

  9. 图片 css剪切,等比例缩放

    object-fit: cover; .img1 {//自定义图片宽高,并且等比例缩放 width: 200px; height: 400px; object-fit: cover; }

随机推荐

  1. STM32之独立看门狗与窗口看门狗总结

    一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...

  2. OpenResty(nginx_lua_module)做ES代理以及备份ES数据

    #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...

  3. Spring aop 原始的工作原理的理解

    理解完aop的名词解释,继续学习spring aop的工作原理. 首先明确aop到底是什么东西?又如何不违单一原则并实现交叉处理呢? 如果对它的认识只停留在面向切面编程,那就脏了.从oop(Objec ...

  4. noip2010-t3

    [题目描述] S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来 ...

  5. shell脚本编译安装LAMP环境

    #filename lamp.sh#version Centos6.7;apache2.4.23;mariadb-5.5.40;php5.5.38#data 2016/09/28#mail 23853 ...

  6. hadoop显示ConnectionrRefused

    产生原因重启了服务器 (1)在安装目录/root/cloud/hadoop-2.2.0/ 重新hdfs namenode -format (2) 目录/root/cloud/hadoop-2.2.0/ ...

  7. 『TCP/IP详解——卷一:协议』读书笔记——15

    2013-08-25 13:39:40 第6章 ICMP:Internet控制报文协议 6.1 引言 ICMP经常被认为是IP层的一个组成部分.它传递差错报文以及其他需要注意的信息.ICMP报文同通常 ...

  8. Unity中使用多构造函数(转)

    如果要实例化的类只有一个构造函数, 则使用方法很简单使用方法如下: 1 2 3 4 5 6 7 using (IUnityContainer container = new UnityContaine ...

  9. 【转】Chrome快捷键

    感谢原作者:http://www.cnblogs.com/mikalshao/archive/2010/11/03/1868568.html 标签页和窗口快捷键 Ctrl+N 打开新窗口. Ctrl+ ...

  10. Hyper-V初涉_共享式网络链接

    任何一台计算机,如果不能与网络连通,可以说已经失去了大部分的功能,Windows 8尤是如此,虚拟机亦是如此. Hyper-V并不能对物理机的网卡进行识别,所以需要借助虚拟网卡通过物理机的网络共享实现 ...