在大部分WEB程式中,驗證碼控制項的使用時非常常見而且非常必要的,原因大家都應該知道,我就不羅嗦了。但是在WinForm程式中,是否有必要加上一個驗證碼控制項?個人認為,一般的個人使用或者小範圍使用的程式中,這個是沒有必要的;但是相對公用的傳統型應用程式中,加上一個驗證碼控制項也許會更加安全。
現在我給大家介紹一下我自己寫的一個比較簡單的驗證碼控制項。
基本原理:產生一些隨機數,然後將這些隨機數畫在一個Bitmap對象中,並對這個Bitmap進行加噪點,扭曲,畫幹擾線等等,最後放入一個PictureBox容器中顯示出來。
步驟:
① 首先建立一個“Windows 控制項陳列庫項目”並命名為“VerificationCode”。
② 開啟解決方案,重新命名“UserControl1.cs”為“VerificationCode.cs”。
③ 雙擊開啟“VerificationCode.cs”,在其容器內添加一個PictureBox控制項,並重新命名為PicCodeImage
④ 轉到代碼介面,開始編輯代碼。
首先,建立控制項的屬性和欄位,其中Code供外部擷取隨機產生的驗證碼,CodeLenght供外部設定產生驗證碼的長度,預設為4。代碼如下:
//弦值
private static double PI2 = 6.283185307179586476925286766559;
private string _Code;
/// <summary>
/// 驗證碼
/// </summary>
public string Code
{
get
{
return _Code;
}
}
private int _CodeLength = 4;
/// <summary>
/// 驗證碼長度
/// </summary>
public int CodeLength
{
set
{
_CodeLength = value;
}
}
然後,建立產生隨機驗證碼的函數,並根據隨機驗證碼產生圖片並加噪扭曲的函數。代碼如下:
/// <summary>
/// 產生圖片
/// </summary>
/// <param name="code">驗證碼運算式</param>
private Bitmap CreatImage(string code)
{
Bitmap image = new Bitmap((int)Math.Ceiling(code.Length * 19.5), 40);
//建立畫布
Graphics g = Graphics.FromImage(image);
Random random = new Random();
//圖片背景色
g.Clear(Color.White);
//畫圖片背景線
for (int i = 0; i < 10; i++)
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine(new Pen(Color.Black), x1, y1, x2, y2);
}
//畫圖片的前景噪音點
for (int i = 0; i < 50; i++)
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
Font font = new Font("Couriew New", 22, FontStyle.Bold);
System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush
(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.SkyBlue, 1.2f, true);
int w = 2;
int h = 1;
g.DrawString(code, font, brush, w, h);
image = TwistImage(image, true, 5, 5);
//畫圖片的邊框線
g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
return image;
}
///<summary>
///正弦曲線Wave扭曲圖片
///</summary>
///<param name="srcBmp">圖片路徑</param>
///<param name="bXDir">如果扭曲則選擇為True</param>
///<param name="nMultValue">波形的幅度倍數,越大扭曲的程度越高,一般為3</param>
///<param name="dPhase">波形的起始相位,取值區間[0-2*PI)</param>
///<returns></returns>
private Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
{
Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
// 將位元影像背景填充為白色
Graphics graph = Graphics.FromImage(destBmp);
graph.FillRectangle(new SolidBrush(Color.White), 0, 0, destBmp.Width, destBmp.Height);
graph.Dispose();
double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width;
for (int i = 0; i < destBmp.Width; i++)
{
for (int j = 0; j < destBmp.Height; j++)
{
double dx = 0;
dx = bXDir ? (PI2 * (double)j) / dBaseAxisLen : (PI2 * (double)i) / dBaseAxisLen;
dx += dPhase;
double dy = Math.Sin(dx);
// 取得當前點的顏色
int nOldX = 0, nOldY = 0;
nOldX = bXDir ? i + (int)(dy * dMultValue) : i;
nOldY = bXDir ? j : j + (int)(dy * dMultValue);
System.Drawing.Color color = srcBmp.GetPixel(i, j);
if (nOldX >= 0 && nOldX < destBmp.Width
&& nOldY >= 0 && nOldY < destBmp.Height)
{
destBmp.SetPixel(nOldX, nOldY, color);
}
}
}
return destBmp;
}
最後,添加picCodeImage的Click事件,並在事件中觸發產生驗證碼的函數,並將產生的Bitmap作為picCodeImage的映像源;同時在控制項初始化時也觸發該函數。代碼如下:
public VerificationCode()
{
InitializeComponent();
picCodeImage.Image = CreatImage(CreatRandomCode(_CodeLength));
}
private void picCodeImage_Click(object sender, EventArgs e)
{
picCodeImage.Image = CreatImage(CreatRandomCode(_CodeLength));
}
大功告成了!現在可以在一個測試專案中,先給工具列添加該自訂控制項,然後拖放到一個Form中,調用方法為:
if (verificationCode1.Code == textBox1.Text.Trim())
{
MessageBox.Show("驗證碼正確");
}
else
{
MessageBox.Show("驗證碼錯誤");
}
注意:在使用該控制項時,可先行設定一下CodeLength屬性,預設為4,該屬性可控制產生驗證碼的長度。