国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

用ASP.NET在網(wǎng)頁上顯示縮略圖

2024-07-10 13:06:01
字體:
供稿:網(wǎng)友

網(wǎng)站上可能會有很多圖片,比如產(chǎn)品圖片等,而且他們可能大小不一,寬度和高度也不一定一樣,有的很大有的很小。如果放在一張網(wǎng)頁上,可能會破壞版面,但是如果強制讓他們按照指定的寬度和高度顯示,因為比例不同還會出現(xiàn)變形,顯示效果很糟糕,還有最大的缺點是,文件尺寸絲毫沒有變化,當(dāng)圖片很大的時候,用戶想要看到圖片,必須經(jīng)過漫長等待下載圖片,怎么辦呢?

好,這里設(shè)計到了縮略圖,就像windows中的縮略圖查看一樣,你所看到的是從原圖按照1:1比例縮小的圖片,而且滿足規(guī)定在指定寬度和高度的范圍內(nèi)顯示(如果圖片填不滿,就用空白)。縮略圖不是原圖,而是利用原圖實時按照指定大小生成的,他的好處就是你可以充分控制縮略圖的質(zhì)量,寬度高度,文件大小也在合理的范圍內(nèi),省去漫長等待。

本文將討論如何生成縮略圖,舉一反三,又可以派生許多用處,比如,自己寫一個驗證碼控件等。

1、理解對圖片的請求和流
    一般來說,我們用http://xxx/a.aspx對a.aspx網(wǎng)頁請求。asp.net處理了網(wǎng)頁以后,就把該網(wǎng)頁的內(nèi)容發(fā)送回瀏覽器。a.aspx的內(nèi)容一般是含有超文本標(biāo)記的文本文件流,這是誰都不會懷疑的。但是a.aspx不但能夠返回這種非常平常的網(wǎng)頁文本外,把它廣義開來,它其實可以放回任何類型的流數(shù)據(jù)。而,我們只需要對response對象進(jìn)行操作即可改變輸出流的內(nèi)容。
    把圖像文件看作是一個二進(jìn)制流,我們試圖從一個圖像文件創(chuàng)建了他的流對象,并且將流寫入到response.outputstream中,這樣圖像文件就被發(fā)給了請求的瀏覽器。但是瀏覽器還必須要識別出這是一個圖像文件,因此,在發(fā)送這個流之前,將response.contenttype更改成這種圖像文件的mime類型。瀏覽器在收到這個流之后,調(diào)用相關(guān)的應(yīng)用程序,圖像就被顯示在了瀏覽器上。雖然實際地址還是aspx結(jié)尾。
    這樣我們就能很好理解怎么去向用戶發(fā)送標(biāo)記。例如,在一張普通的網(wǎng)頁中寫標(biāo)記img標(biāo)記,使他的src指向a.aspx。瀏覽器在得到這張網(wǎng)頁后,會處理img標(biāo)記的內(nèi)容,并向a.aspx發(fā)出請求,這是a.aspx作為圖像流返回,瀏覽器就將圖片顯示出來。

2、生成縮略圖
    有了上述技術(shù)基礎(chǔ),我們可以建立這樣一個空的aspx網(wǎng)頁,他通過接受傳入的參數(shù),生成縮略圖的流,發(fā)送回瀏覽器。
    我們創(chuàng)建一個名叫g(shù)etthumbnail.aspx的文件,內(nèi)容如下:

<%@ page language="vb" autoeventwireup="false" codebehind="getthumbnail.aspx.vb" inherits="_51use.getthumbnail"%>

這一句page指令僅僅是告訴服務(wù)器,這個文件的隱藏類是_51use.getthumbnail,而如果我們都不作任何操作的話,這個文件最終輸出時空的。
接下來看一下他的隱藏類是如何寫的,在這里我們使用的是b語言:

程序代碼:

public class getthumbnail
    inherits system.web.ui.page

#region " web 窗體設(shè)計器生成的代碼 "

    '該調(diào)用是 web 窗體設(shè)計器所必需的。
    <system.diagnostics.debuggerstepthrough()> private sub initializecomponent()

    end sub

    '注意: 以下占位符聲明是 web 窗體設(shè)計器所必需的。
    '不要刪除或移動它。
    private designerplaceholderdeclaration as system.object

    private sub page_init(byval sender as system.object, byval e as system.eventargs) handles mybase.init
        'codegen: 此方法調(diào)用是 web 窗體設(shè)計器所必需的
        '不要使用代碼編輯器修改它。
        initializecomponent()
    end sub

#end region

    private sub page_load(byval sender as system.object, byval e as system.eventargs) handles mybase.load
        '在此處放置初始化頁的用戶代碼
        '獲取幾個參數(shù),用以生成縮略圖片
        '設(shè)置一個默認(rèn)參數(shù)生成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)

            '設(shè)置畫布的描繪質(zhì)量
            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

            '設(shè)置壓縮質(zhì)量
            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

            '獲得包含有關(guān)內(nèi)置圖像編碼解碼器的信息的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事件處理函數(shù)中,先獲取要生成縮略圖的原始文件的路徑,和縮略圖的寬度高度。
然后設(shè)置了一個子函數(shù)getnewsize用以計算真正縮略圖的大小(為什么還要計算阿?因為縮略圖的寬高比和原始圖片的寬高比不一樣,縮小的圖片要保證比例,按照比例縮小的原始圖片,是按照約束在指定縮略圖寬高范圍內(nèi)的原則,填充不滿的地方使用背景色填補空白。另外,原圖比縮略圖小的話,我們就不做放大,而是按原圖輸出,所以計算是必須的)。

我們從原始圖像創(chuàng)建了他的image對象,并獲得它的格式等信息,稍后用得到。

接下來新建一個bitmap對象,并由新的bitmap對象創(chuàng)建畫板。設(shè)置畫筆質(zhì)量為高,交錯模式為高質(zhì)量立方式,這些的目的是使用最好的質(zhì)量描繪縮略圖,否則圖片縮小后信息丟失圖片失真就不好看了。接著,用指定的寬度和高度將原始圖像的image對象“畫”在新的畫板上。

修改response.contenttype,這一步是告訴瀏覽器發(fā)送回的流的mime類型,這個內(nèi)容包含在http header中發(fā)送給瀏覽器。

圖像畫好了,現(xiàn)在我們要將其壓縮一下,因為位圖對象是很大的,不利于傳輸。因此下面的操作,我們設(shè)定一些高質(zhì)量的壓縮參數(shù),根據(jù)獲得的ici(圖像編碼解碼器信息),使用bitmap的save方法將圖片保存在response.outputstream流中。

這樣在瀏覽器看來,對該網(wǎng)頁的請求,相當(dāng)于對一個圖片文件的請求,只不過圖片是實時生成的,只需傳遞參數(shù)合法有效,即可得到該圖片的縮略圖。

3、使用縮略圖
    使用縮略圖就變得相對簡單了,只需要在url后附上參數(shù)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>


代碼中藍(lán)色部分就是對該頁請求的url,使用<%# server.urlencode(configurationsettings.appsettings("wareimgpath") & container.dataitem("wareimgpath"))%>語句從數(shù)據(jù)庫獲得路徑和文件名適當(dāng)構(gòu)造成一個有效的請求路徑。工作就算完成了。

下面就等著看看縮略圖的效果:

后記
    本文中所述的縮略圖生成法,使用的是流的概念,和文件系統(tǒng)也不沾邊,因此這種方式可以跳過對文件系統(tǒng)權(quán)限檢查,百分之百正確運行。當(dāng)然,也可以借助文件系統(tǒng)。另外,根據(jù)上面流輸出的概念,舉一反三,可以弄出很多用法,例如neodynamic的條形碼控件,你會發(fā)現(xiàn)條形碼圖片的路徑居然就是本頁頁面,他巧妙地將對本頁的請求通過對幾個特征參數(shù)的判定而轉(zhuǎn)向生成圖片流,從而達(dá)到了不添加任何頁面,不借助文件系統(tǒng)的“神奇效果”,只需要一個dll即可使用。
    另外,很多人問生成驗證碼圖片,也可以使用這樣的思路,自己做一個這樣的控件,或者網(wǎng)頁。如果能做自定義控件更好。相信大家有這個能力。
    最后,還是提倡大家都去翻翻msdn,有很大幫助。安裝vs的時,7cd裝的版本其中三張是msdn library,包含了近乎所有你想要了解的東西。如果有時間,不妨多訪問一下msdn中國,不定期會有一些優(yōu)秀的文章在上面。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 利川市| 当阳市| 老河口市| 屏东县| 海口市| 县级市| 富川| 芮城县| 竹溪县| 秦安县| 永嘉县| 邹城市| 茌平县| 松潘县| 桂阳县| 集安市| 观塘区| 神农架林区| 土默特右旗| 襄汾县| 秭归县| 博客| 宝山区| 平遥县| 万源市| 英德市| 寿宁县| 天峨县| 盐池县| 扎兰屯市| 泸溪县| 屏南县| 保定市| 六盘水市| 旬邑县| 铁力市| 扬中市| 彭州市| 河北省| 维西| 怀仁县|