程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> [圖文]用ASP.NET在網頁上顯示縮略圖

[圖文]用ASP.NET在網頁上顯示縮略圖

編輯:.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)
 &nbsFor
   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中國,不定期會有一些優秀的文章在上面。
  
   限於作者水平,出錯難免,歡迎批評指正!
  
  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved