用ASP.NET在网页上显示缩略图

asp.net|缩略图|网页|显示

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

好,这里设计到了缩略图,就像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语言:

程序代码:

Public Class GetThumbnail
    Inherits System.Web.UI.Page

#Region " Web 窗体设计器生成的代码 "

    '该调用是 Web 窗体设计器所必需的。
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub

    '注意: 以下占位符声明是 Web 窗体设计器所必需的。
    '不要删除或移动它。
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: 此方法调用是 Web 窗体设计器所必需的
        '不要使用代码编辑器修改它。
        InitializeComponent()
    End Sub

#End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        '在此处放置初始化页的用户代码
        '获取几个参数,用以生成缩略图片
        '设置一个默认参数生成BitMap
        Response.Clear()
        Try
            Dim originalFileName As String = Server.MapPath(Request("fn"))
            Dim thumbnailWidth As Integer = Request("tw")
            Dim thumbnailHeight As Integer = Request("th")

            Dim img As System.Drawing.Image = System.Drawing.Image.FromFile(originalFileName)
            Dim thisFormat As System.Drawing.Imaging.ImageFormat = img.RawFormat
            Dim newSize As System.Drawing.Size = Me.GetNewSize(thumbnailWidth, thumbnailHeight, img.Width, img.Height)
            Dim outBmp As New System.Drawing.Bitmap(thumbnailWidth, thumbnailHeight)
            Dim g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(outBmp)

            '设置画布的描绘质量
            g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
            g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
            g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
            g.Clear(System.Drawing.Color.FromArgb(255, 249, 255, 240))
            g.DrawImage(img, New Rectangle((thumbnailWidth - newSize.Width) / 2, (thumbnailHeight - newSize.Height) / 2, newSize.Width, newSize.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel)
            g.Dispose()

            If thisFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif) Then
                Response.ContentType = "image/gif"
            Else
                Response.ContentType = "image/jpeg"
            End If

            '设置压缩质量
            Dim encoderParams As New System.Drawing.Imaging.EncoderParameters
            Dim quality(0) As Long
            quality(0) = 100
            Dim encoderParam As New System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality)
            encoderParams.Param(0) = encoderParam

            '获得包含有关内置图像编码解码器的信息的ImageCodecInfo 对象。
            Dim arrayICI() As System.Drawing.Imaging.ImageCodecInfo = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()
            Dim jpegICI As System.Drawing.Imaging.ImageCodecInfo = Nothing
            For fwd As Integer = 0 To arrayICI.Length - 1
                If arrayICI(fwd).FormatDescription.Equals("JPEG") Then
                    jpegICI = arrayICI(fwd)
                    Exit For
                End If
            Next

            If Not jpegICI Is Nothing Then
                outBmp.Save(Response.OutputStream, jpegICI, encoderParams)
            Else
                outBmp.Save(Response.OutputStream, thisFormat)
            End If
        Catch ex As Exception

        End Try
    End Sub

    Function GetNewSize(ByVal maxWidth As Integer, ByVal maxHeight As Integer, ByVal width As Integer, ByVal height As Integer) As System.Drawing.Size
        Dim w As Double = 0.0
        Dim h As Double = 0.0
        Dim sw As Double = Convert.ToDouble(width)
        Dim sh As Double = Convert.ToDouble(height)
        Dim mw As Double = Convert.ToDouble(maxWidth)
        Dim mh As Double = Convert.ToDouble(maxHeight)

        If sw < mw And sh < mh Then
            w = sw
            h = sh
        ElseIf (sw / sh) > (mw / mh) Then
            w = maxWidth
            h = (w * sh) / sw
        Else
            h = maxHeight
            w = (h * sw) / sh
        End If
        Return New System.Drawing.Size(Convert.ToInt32(w), Convert.ToInt32(h))
    End Function
End Class

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

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

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

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

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

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

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

<asp:Repeater id=repWareList runat="server" DataSource="<%# dsWareList %>">
  <ItemTemplate>
    <div class="ItemContainer">
      <p><img src='../lib/GetThumbnail.aspx?fn=<%# Server.UrlEncode(Configurationsettings.AppSettings("WareImgPath") & Container.DataItem("WareImgPath"))%>&tw=120&th=120' width="120" height="120" ></p>
    </div>
  </ItemTemplate>
</asp:Repeater>
代码中蓝色部分就是对该页请求的URL,使用<%# Server.UrlEncode(Configurationsettings.AppSettings("WareImgPath") & Container.DataItem("WareImgPath"))%>语句从数据库获得路径和文件名适当构造成一个有效的请求路径。工作就算完成了。

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

后记
    本文中所述的缩略图生成法,使用的是流的概念,和文件系统也不沾边,因此这种方式可以跳过对文件系统权限检查,百分之百正确运行。当然,也可以借助文件系统。另外,根据上面流输出的概念,举一反三,可以弄出很多用法,例如NeoDynamic的条形码控件,你会发现条形码图片的路径居然就是本页页面,他巧妙地将对本页的请求通过对几个特征参数的判定而转向生成图片流,从而达到了不添加任何页面,不借助文件系统的“神奇效果”,只需要一个DLL即可使用。
    另外,很多人问生成验证码图片,也可以使用这样的思路,自己做一个这样的控件,或者网页。如果能做自定义控件更好。相信大家有这个能力。
    最后,还是提倡大家都去翻翻MSDN,有很大帮助。安装VS的时,7CD装的版本其中三张是MSDN Library,包含了近乎所有你想要了解的东西。如果有时间,不妨多访问一下MSDN中国,不定期会有一些优秀的文章在上面。

时间: 2024-10-31 15:05:11

用ASP.NET在网页上显示缩略图的相关文章

c#-asp的web form中,在后台生成了表,怎样让表在网页上显示

问题描述 asp的web form中,在后台生成了表,怎样让表在网页上显示 自己在后台动态生成了一个表,但是在网页上面显示不出来,不知道为什么,表的动态生成写在Page__load()函数中,页面设计如下: <%@Page Language="C#" AutoEventWireup="true" CodeBehind="Reservationa.aspx.cs" Inherits="HT.Reservationa" Ma

asp.net在网页中显示上传的Word文档

问题描述 asp.net在网页中显示上传的Word文档内容要怎么做pix文件夹保存的是上传的文件地址存在数据库里(SqlServer2005)datatbledt=BLL.Product.GetProductDetail(id);//读出地址dt.Rows[0]["ProductPix"].ToString()各位老大帮忙了 解决方案 解决方案二:没人理我啊老大些帮忙啊解决方案三:如果要显示word的格式,需要安装插件吧?如果只是显示内容,图片什么的都不要,可以利用程序之间读出来引用m

菜鸟刚学html5,要通过什么方法才能在网页上显示表格,表格内容来自远程数据库sql

问题描述 菜鸟刚学html5,要通过什么方法才能在网页上显示表格,表格内容来自远程数据库sql 要在网页上显示表格内容,内容来自远程数据库sql,网页是asp.net 解决方案 asp.net不是有datalist,repater那种控件,你用repeater 的itemtemplate模板放tr,然后设置repeater数据源进行绑定就行了 解决方案二: 应该可以在前台用ajax获取 我个人之前试用过的方法是让后台生成接口,前台直接调用接口获取数据,并呈现出来. 解决方案三: 和html5没有

报表-怎么根据用户的权限不同在网页上显示出有权限查看的内容

问题描述 怎么根据用户的权限不同在网页上显示出有权限查看的内容 单位的内部管理系统,不同的人员可以进行登录,登录后,根据不同的职位和权限,在同一个页面上每个人能看到的内容是不同,比如说公司的销售可以查看自己的订单,销售主管,可以查所有销售的订单,而技术部门不能查看这些信息. 解决方案 什么语言?自己判断下权限显示对应内就好了,asp.net将内容放入 <asp:Panel runat="server" ID="pl1"></asp:Panel>

JS文件中的中文在网页上显示为乱码解决方法

JS编码转换,这句话本身就是一句具有二重义的话.通常理解为JS文件里能转换编码的代码,但是,我所碰到的问题并不是这样的,是要解决JS文件本身的编码问题,它是UTF-8编码的还是ANSI编码的?在百度.谷歌上一搜,大家都是说通过JAVA后台处理来解决编码问题,试问,这样能解决JS文件本身的编码问题吗? 之所以提出JS文件本身编码问题,是因为JS文件的编码不同,造成了中文显示为乱码. 通常,在Eclipse中建立一个JS文件(含有中文),在Eclipse的编辑器中看到的中文都很正常,但是显示在网页上

控件-c#winform显示html文本在网页上显示的内容

问题描述 c#winform显示html文本在网页上显示的内容 我的想法是winform一个控件(可能是文本框或者是什么)写HTML语言也就是这个文本的内容可能是 然后另外一个控件就把这些图片显示出来,可能不是使用webBrowser这个控件 也许只需要一个richtextbox控件来显示就行了我并不是要显示出一个网页,而是要显示出这个文本标记语言的内容 解决方案 那你就把页面源码读出HTML字符串,然后直接给RichEditCtrl控件显示

html格式的用浏览器打开可是网页上显示的是空白的但是有标头

问题描述 html格式的用浏览器打开可是网页上显示的是空白的但是有标头 html格式的用浏览器打开可是网页上显示的是空白的但是有标头 蛋疼了 这搞的我真是 小弟是新手

当SQL SERVER的表记录上万时,前台网页上显示就很慢?

问题描述 当SQLSERVER的表记录上万时,前台网页上显示就很慢为什么?我已经做了分页但还是不行,而且第一页会显示所有记录从第二页开始分页,我用的ADO.NET中的Sqldatadapte类,然后填充到DataSet对象中. 解决方案 解决方案二:这个是正常的,数据量大的时候用存储过程来写解决方案三:给你个例子:http://blog.csdn.net/heqi915/archive/2007/02/27/1516075.aspx解决方案四:你第一页可以只显示pagesize的记录数啊我正在写

visio嵌套在网页上显示

问题描述 目前在做一个功能:需求是在网页上面在(譬如:jsp)里面加载读取显示visio(文件后缀:点vsd),把visio绘制的图像模型(流程图)在网页上显示:功能就像是网页上显示world文档(excel文档)一样.很急...希望大家给我建议,或者链接,或者相应学习资料,或者小Damo. 解决方案 解决方案二: 解决方案三:参考这个帖子http://bbs.csdn.net/topics/390186935