以下是代碼片段: Imports System.IO Imports System.Drawing Imports System.Drawing.Imaging Imports System.Drawing.Drawing2D Partial Class VerifyChar Inherits System.Web.UI.Page Private Const PI As Double = 3.14159265358979 Private Const PI2 As Double = 6.28318530717959 Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache) ’不緩存 Dim x, y, x1, y1 As Single Dim PenWidth1, PenWidth2, VerifyVharFont As Integer Dim VerifyChar As String = RndChar(4) ’RndChar是一個自定義函數 Dim Img As System.Drawing.Bitmap Dim g As Graphics Dim backBrush As Brush = Brushes.DimGray Dim textBrush As Brush = Brushes.Black VerifyVharFont = Int(7 * Rnd()) + 14 ’驗證碼字元字型大小随機生成 Dim textFont As New Font("Arial", VerifyVharFont, FontStyle.Strikeout) ’驗證碼字型 Dim ms As MemoryStream Dim gWidth As Integer = Int(Len(VerifyChar)) * VerifyVharFont + VerifyVharFont ’驗證區寬度。如果字元都為W,不加寬是不行的 Img = New Bitmap(gWidth, 30) ’驗證區高度 ’生成随機背景顔色 Dim nRed, nGreen, nBlue As Integer ’ 背景的三元色 Dim rd = New Random ’(CInt(System.DateTime.Now.Ticks)) nRed = rd.Next(255) Mod 128 + 128 nGreen = rd.Next(255) Mod 128 + 128 nBlue = rd.Next(255) Mod 128 + 128 ’在圖檔框picCanvas上面建立一個新的空白Graphics g = Graphics.FromImage(Img) ’填充位圖背景 g.FillRectangle(New SolidBrush(System.Drawing.Color.FromArgb(nRed, nGreen, nBlue)), 0, 0, Img.Width, Img.Height) ’随機輸出噪音線 Dim i As Int32 For i = 0 To 2 Randomize() x = Img.Width * Rnd() y = Img.Height * Rnd() x1 = Img.Width * Rnd() y1 = Img.Height * Rnd() PenWidth1 = 2 * Rnd() ’修改參數可獲得不同的效果 g.DrawLine(New Pen(backBrush, PenWidth1), x, y, x1, y1) Next ’随機輸出噪點 PenWidth2 = 2 ’修改參數可獲得不同的效果 For i = 0 To 10 Randomize() x = Img.Width * Rnd() y = Img.Height * Rnd() nRed = rd.Next(255) Mod 128 + 128 nGreen = rd.Next(255) Mod 128 + 128 nBlue = rd.Next(255) Mod 128 + 128 g.DrawRectangle(New Pen(Color.FromArgb(nRed, nGreen, nBlue), PenWidth2), x, y, 1, 1) Next ’文字的位置 x = 16 * Rnd() - 6 ’随機産生X軸位置,增加程式識别難度 y = 0 ’随機畫3D背景 Dim S3d As Single = Rnd() If S3d > 0.9 Then For i = 1 To 0 Step -1 g.DrawString(VerifyChar, textFont, backBrush, x - i, y + i) Next End If ’将全局變換平移(x, y),也就是使畫布上将要畫的所有内容向左邊移動x,向下移動y g.TranslateTransform(1.5, 1) ’做切變,将原始矩形的下邊緣水準移動矩形高度的0.2倍 Dim textTransform As Matrix = g.Transform textTransform.Shear(0.2, 0) g.Transform = textTransform ’畫出文字 g.DrawString(VerifyChar, textFont, textBrush, x, y) Me.Session("VerifyChar") = VerifyChar ’将驗證字元寫入Session,供前台調用 ’扭曲驗證字元。TwistImage參數可自行修改 Dim Twist1, Twist2 As Single If S3d > 0.9 Then ’3D背景減少扭曲 Twist1 = 0 Twist2 = 0 Else Twist1 = Rnd() * 3 ’扭曲參數随機生成 Twist2 = Rnd() * 2 ’扭曲參數随機生成 End If Img = TwistImage(Img, True, -Twist1, -Twist2) Img = TwistImage(Img, False, Twist1, Twist2) ’多扭曲幾次也沒關系,隻是消耗伺服器資源多些 ms = New MemoryStream Img.Save(ms, ImageFormat.Png) Response.ClearContent() ’需要輸出圖象資訊 要修改HTTP頭 Response.ContentType = "image/Png" Response.BinaryWrite(ms.ToArray()) g.Dispose() Img.Dispose() Response.End() End Sub ’函數名稱:RndChar ’函數參數:VcodeNum--設定傳回随機字元串的位數 ’函數功能:産生指定長度的由數字和字元組成的随機字元串 Function RndChar(ByVal VcodeNum) As String Dim Vchar As String = "3,3,5,5,6,6,7,7,9,9,A,C,E,F,G,H,K,L,M,N,P,R,T,X,Y,Z" ’定義驗證碼字元及出現頻次 Dim VcArray() As String = Split(Vchar, ",") ’将字元串生成數組 Vchar = "" Dim i As Byte For i = 0 To Int(VcodeNum * Rnd()) + 1 ’確定最少2個字元,最多VcodeNum+1個字元 Randomize() Vchar = Vchar & VcArray(Int(25 * Rnd())) ’數組一般從0開始讀取,是以這裡為25*Rnd Next Return Vchar End Function ’函數名稱:TwistImage ’函數參數: dMultValue-波形的幅度倍數;dPhase波形的起始相位,取值區間[0-2*PI);bXDir-扭曲方式 ’函數功能:正弦曲線Wave扭曲圖檔。函數可以疊加使用,以獲得不同方式不同程度的效果 ’這個天才的函數,已經無法考證出處了。感謝原作者! Public Function TwistImage(ByVal srcBmp As Bitmap, ByVal bXDir As Boolean, ByVal dMultValue As Double, ByVal dPhase As Double) As Bitmap Dim destBmp = New Bitmap(srcBmp.Width, srcBmp.Height) Dim dBaseAxisLen As Double = IIf(bXDir, CDbl(destBmp.Height), CDbl(destBmp.Width)) ’ToDo: Unsupported feature: conditional (?) operator. Dim i As Integer For i = 0 To destBmp.Width - 1 Dim j As Integer For j = 0 To destBmp.Height - 1 Dim dx As Double = 0 dx = IIf(bXDir, PI2 * CDbl(j) / dBaseAxisLen, PI2 * CDbl(i) / dBaseAxisLen) ’ToDo: Unsupported feature: conditional (?) operator. dx += dPhase Dim dy As Double = Math.Sin(dx) ’ 取得目前點的顔色 Dim nOldX As Integer = 0 Dim nOldY As Integer = 0 nOldX = IIf(bXDir, i + CInt(dy * dMultValue), i) ’ToDo: Unsupported feature: conditional (?) operator. nOldY = IIf(bXDir, j, j + CInt(dy * dMultValue)) ’ToDo: Unsupported feature: conditional (?) operator. Dim color As System.Drawing.Color = srcBmp.GetPixel(i, j) If nOldX >= 0 And nOldX < destBmp.Width And nOldY >= 0 And nOldY < destBmp.Height Then destBmp.SetPixel(nOldX, nOldY, color) End If Next j Next i Return destBmp End Function End Class |