• C#自定义控件验证码控件


         在大部分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,该属性可控制生成验证码的长度。

  • 相关阅读:
    我的Firefox
    九成偏股基金净值增长弱于大盘 仅18只跑赢指数
    大事记:
    Symantec AntiVirus企业版(接受管理)客户机端卸载方法
    CDP
    两行代码解决iOS上拉下拉时,底部栏顶部栏跟随手势滚动
    8Windows概要
    4断点和单步执行
    win7下windbg本机内核调试
    windbg技巧看和改标志位创建进程时断下
  • 原文地址:https://www.cnblogs.com/oyzl5zl/p/2319142.html
Copyright © 2020-2023  润新知