之前寫了一些ASP.net動態縮圖的東西....
但發現還不是很完美...
ex:
1.不能等比例縮圖,一定要決定寬高
2.不能截圖片的寬與高
3.只能針對固定路徑的圖片縮圖
所以想說來改一下....
然後完成後的 code 如下.....
(我是寫成泛型處理常式)
<%@ WebHandler Language="VB" Debug="true" %>
Imports System
Imports System.Web
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Public Class RsizeImg : Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Response.ContentType = "image/jpeg"
context.Response.BufferOutput = True
Dim files As String = context.Request("file") '檔名
Dim Folder As String = "" '要存放縮圖的資料夾
Dim filename As String = ""
Dim Saveas As String = ""
Dim w As Integer = 0 '要縮圖的寬
Dim h As Integer = 0 '要縮圖的高
Dim cuth As Integer = 0 '要截圖的高
Dim cutw As Integer = 0 '要截圖的寬
If context.Request("w") IsNot Nothing Then
w = context.Request("w")
End If
If context.Request("h") IsNot Nothing Then
h = context.Request("h")
End If
If context.Request("f") IsNot Nothing Then
Folder = context.Request("f") & "\"
End If
If context.Request("cuth") IsNot Nothing Then
cuth = context.Request("cuth")
End If
If context.Request("cutw") IsNot Nothing Then
cutw = context.Request("cutw")
End If
'縮圖輸出位置
Dim End_path As String = "Z:\ImagesUpload\" & Folder & "\resize\"
If InStr(files, "/") > 0 Then
filename = Right(files, InStrRev(files, "/") - 1)
Else
filename = files
End If
'不同格式的圖產生不同的檔名
If cuth > 0 Then
Saveas = End_path & filename & "_" & w & "_" & h & "_ch" & cuth & ".jpg"
ElseIf cutw > 0 Then
Saveas = End_path & filename & "_" & w & "_" & h & "_cw" & cutw & ".jpg"
Else
Saveas = End_path & filename & "_" & w & "_" & h & ".jpg"
End If
Dim fileExists As Boolean
'判斷有無縮圖,有則直接用縮圖不用再產生了
fileExists = My.Computer.FileSystem.FileExists(Saveas)
If fileExists = False Then
'原圖位置,根據傳入的folder名稱切換資料夾
Dim SFileStream As FileStream = File.OpenRead("Z:\ImagesUpload\" & Folder & filename)
Dim TFileStream As FileStream = File.Create(Saveas)
ResizeImage(0.1, SFileStream, TFileStream, w, h, cutw, cuth)
SFileStream.Close()
TFileStream.Close()
context.Response.ContentType = "image/jpeg"
context.Response.WriteFile(Saveas)
Else
context.Response.ContentType = "image/jpeg"
context.Response.WriteFile(Saveas)
End If
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
Function ThumbNailCallBack() As Boolean
Return False
End Function
Public Sub ResizeImage(ByVal scaleFactor As Double, ByVal fromStream As Stream, ByVal toStream As Stream, ByVal w As Integer, ByVal h As Integer, ByVal cutw As Integer, ByVal cuth As Integer)
Dim image As System.Drawing.Image = System.Drawing.Image.FromStream(fromStream)
If h = 0 Then
h = image.Height
End If
If w = 0 Then
w = image.Width
End If
'這函數網路上ㄎㄧㄤ來的...計算圖片等比寬高並回傳integer陣列
Dim thumbnailScale As Integer() = getThumbnailImageScale(w, h, image.Width, image.Height)
Dim cw As Integer = w
Dim ch As Integer = h
If cutw > 0 Then
cw = cutw
End If
If cuth > 0 Then
ch = cuth
End If
'如果要截的寬度超過等比縮圖的寬度~就以等比縮的寬為主
If thumbnailScale(0) < cw Then
cw = thumbnailScale(0)
End If
'同上
If thumbnailScale(1) < ch Then
ch = thumbnailScale(1)
End If
'產生圖片囉,順便截圖
Dim thumbnailBitmap As Bitmap = New Bitmap(cw, ch)
Dim thumbnailGraph As Graphics = Graphics.FromImage(thumbnailBitmap)
'這些屬性是要高品質的意思
thumbnailGraph.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
thumbnailGraph.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
thumbnailGraph.InterpolationMode = Drawing2D.InterpolationMode.High
'產生矩形的畫布並將產生的圖形放到畫布中
'MSDN http://msdn.microsoft.com/en-us/library/yws82c40.aspx
Dim imageRectangle As Rectangle = New Rectangle(0, 0, thumbnailScale(0), thumbnailScale(1))
thumbnailGraph.DrawImage(image, imageRectangle)
'存檔 + 物件消滅
thumbnailBitmap.Save(toStream, image.RawFormat)
thumbnailGraph.Dispose()
thumbnailBitmap.Dispose()
image.Dispose()
End Sub
Function getThumbnailImageScale(ByVal maxWidth As Integer, ByVal maxHeight As Integer, ByVal oldWidth As Integer, ByVal oldHeight As Integer) As Integer()
Dim result() As Integer = New Integer() {0, 0}
Dim widthDividend As Single, heightDividend As Single, commonDividend As Single
widthDividend = oldWidth / maxWidth
heightDividend = oldHeight / maxHeight
If (heightDividend > widthDividend) Then
commonDividend = heightDividend
Else
commonDividend = widthDividend
End If
result(0) = CType((oldWidth / commonDividend), Integer)
result(1) = CType((oldHeight / commonDividend), Integer)
Return result
End Function
End Class
使用方式 :
1.圖片等比縮至300後存放到 starwear資料夾,日後如有需要就不用再產生一遍了
http://xxxxx.xxx.com.tw/ResizeImg.ashx?file=20110110565.jpg&f=starwear&w=300
2.圖片高等比縮至300
http://xxxxx.xxx.com.tw/ResizeImg.ashx?file=20110110565.jpg&f=starwear&h=300
3.圖片高等比縮至300,並將高截至100
http://xxxxx.xxx.com.tw/ResizeImg.ashx?file=20110110565.jpg&f=starwear&h=300&cuth=100
參考資料 : http://blog.lansea-chu.com/index.php/archives/330
(我參考等比縮圖的地方 ^^")