C#分享辅助类:验证码图片生成类(VerifyCodeHandler)

30 篇文章 1 订阅

名称

方法

生成检验码图片

BuildVerifyCode

BuildVerifyCodeImage

TwistImage

生成随机字符码

GetVerifyCode

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Web;
using System.IO;
using System.Security.Cryptography;

namespace Wsfly
{
    /// <summary>
    /// 验证码
    /// </summary>
    public class VerifyCodeHandler
    {
        #region 属性

        #region 验证码长度(默认5个验证码的长度)

        int length = 5;
        public int Length
        {
            get { return length; }
            set { length = value; }
        }
        #endregion

        #region 验证码字体大小(默认24像素)

        int fontSize = 24;
        public int FontSize
        {
            get { return fontSize; }
            set { fontSize = value; }
        }
        #endregion

        #region 边框补(默认4像素)

        int padding = 4;
        public int Padding
        {
            get { return padding; }
            set { padding = value; }
        }
        #endregion

        #region 自定义背景色(默认白色)

        Color backgroundColor = Color.White;
        public Color BackgroundColor
        {
            get { return backgroundColor; }
            set { backgroundColor = value; }
        }
        #endregion

        #region 自定义字体数组

        string[] fonts = { "Arial", "Georgia", "Rosewood Std", "Ravie" };
        public string[] Fonts
        {
            get { return fonts; }
            set { fonts = value; }
        }
        #endregion

        #region 自定义随机码字符串序列(使用逗号分隔)

        string _code1 = "2,3,4,5,6,7,8,9";//没有0,1
        string _code2 = "a,b,c,d,e,f,g,h,i,j,k,m,n,p,q,r,s,t,u,v,w,x,y,z";//没有l,o
        string _code3 = "A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z";//没有I,O
        string _codeSerial = null;

        /// <summary>
        /// 随机验证码序列 (默认:数字大小写字母)
        /// </summary>
        public string CodeSerial
        {
            get
            {
                if (!string.IsNullOrEmpty(_codeSerial))
                {
                    return _codeSerial;
                }
                else
                {
                    switch (this.VerifyCodeHardType)
                    {
                        case VerifyCodeHardType.数字: return _code1;
                        case VerifyCodeHardType.小写字母: return _code2;
                        case VerifyCodeHardType.大写字母: return _code3;
                        case VerifyCodeHardType.大小写字母: return _code2 + "," + _code3;
                        case VerifyCodeHardType.数字小写字母: return _code1 + "," + _code2;
                        case VerifyCodeHardType.数字大写字母: return _code1 + "," + _code3;
                        case VerifyCodeHardType.数字大小写字母:
                        default: return _code1 + "," + _code2 + "," + _code3;
                    }
                }
            }
            set { _codeSerial = value; }
        }
        #endregion

        #region 自定义难度
        VerifyCodeHardType _verifyCodeHardType = VerifyCodeHardType.数字大小写字母;
        /// <summary>
        /// 验证码难度
        /// </summary>
        public VerifyCodeHardType VerifyCodeHardType
        {
            get { return _verifyCodeHardType; }
            set { _verifyCodeHardType = value; }
        }
        #endregion

        #endregion

        #region 方法

        #region 生成校验码图片
        /// <summary>
        /// 生成检验码图片
        /// </summary>
        /// <returns></returns>
        public Bitmap BuildVerifyCode(string sessionKey, out string code)
        {
            ///生成验证码
            code = GetVerifyCode();
            return BuildVerifyCodeImage(code);
        }
        /// <summary>
        /// 生成检验码图片
        /// </summary>
        /// <returns></returns>
        public Bitmap BuildVerifyCode(int len, string sessionKey, out string code)
        {
            ///生成验证码
            code = GetVerifyCode(len);
            return BuildVerifyCodeImage(code);
        }
        /// <summary>
        /// 生成校验码图片
        /// </summary>
        /// <param name="code">已经生成的随机码</param>
        /// <returns>位图</returns>
        private Bitmap BuildVerifyCodeImage(string code)
        {
            //随机种子
            Random rand = new Random(GetNewSeed());
            //左侧空白宽度
            int spaceWidth = rand.Next(20, 60);

            int fSize = FontSize;
            int fWidth = fSize + Padding;

            int imageWidth = (int)(code.Length * fWidth) + 4 + Padding * 2;
            int imageHeight = fSize * 2 + Padding;

            //生成图片
            System.Drawing.Bitmap image = new System.Drawing.Bitmap(imageWidth, imageHeight);

            //GDI生成图片
            Graphics g = Graphics.FromImage(image);
            //设置文本输出质量
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            //清空背景
            g.Clear(BackgroundColor);

            float top = 0, top1 = 1, top2 = 1;
            float left = spaceWidth;

            int n1 = (imageHeight - FontSize - Padding * 2);
            int n2 = n1 / 4;

            top1 = n2;
            top2 = n2 * 2;

            //字体样式——大小、字体
            Font font;
            //字体颜色——蓝色
            Brush brush = new System.Drawing.SolidBrush(Color.Blue);
            //钢笔
            Pen pen = new Pen(brush, 1);

            /* 取消曲线
            //定义曲线转折点 
            int count = 10;
            Point[] points = new Point[count];
            for (int i = 0; i < count; i++)
            {
                points[i].X = (imageWidth / (count - 1)) * i;
                points[i].Y = imageHeight / 2 + rand.Next(-5, 9);
            }
            
            //绘制曲线
            g.DrawCurve(pen, points, 0.5F);
            */

            //随机字体和颜色的验证码字符
            int findex, fsindex;
            for (int i = 0; i < code.Length; i++)
            {
                findex = rand.Next(Fonts.Length - 1);
                fsindex = rand.Next(5);

                //字体样式
                System.Drawing.FontStyle fontStyle;
                switch (fsindex)
                {
                    case 2: fontStyle = FontStyle.Italic; break;
                    case 3: fontStyle = FontStyle.Bold; break;
                    default: fontStyle = FontStyle.Regular; break;
                }

                //字符字体
                font = new System.Drawing.Font(Fonts[findex], fSize, fontStyle);
                //Size sz = TextRenderer.MeasureText(measureString, font);

                //验证码字符
                string codeText = code.Substring(i, 1);
                //SizeF fontSize = g.MeasureString(codeText,font);
                Size fontSize = System.Windows.Forms.TextRenderer.MeasureText(codeText, font);

                //字符定位
                if (i % 2 == 1) { top = top2; }
                else { top = top1; }

                //画字符
                g.DrawString(codeText, font, brush, left, top);

                //左侧距离
                left += fontSize.Width / 2 - 3;
            }

            //释放资源
            g.Dispose();

            //扭曲图片
            image = TwistImage(image, true, 3, 2);

            //返回图片
            return image;
        }

        private const double PI = 3.1415926535897932384626433832795;
        private const double PI2 = 6.283185307179586476925286766559;
        /// <summary>
        /// 正弦曲线Wave扭曲图片
        /// image = TwistImage(image, true, 3, 5);
        /// </summary>
        /// <param name="srcBmp"></param>
        /// <param name="bXDir"></param>
        /// <param name="nMultValue">波形的幅度倍数</param>
        /// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
        /// <returns></returns>
        public System.Drawing.Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
        {
            System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);

            // 将位图背景填充为白色
            System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(destBmp);
            graph.FillRectangle(new SolidBrush(BackgroundColor), 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;
        }
        #endregion

        #region 生成随机字符码
        /// <summary>
        /// 生成随机字符码
        /// </summary>
        /// <param name="codeLen">随机码长度</param>
        /// <returns>产生的随机码</returns>
        public string GetVerifyCode(int len)
        {
            if (len <= 0) len = Length;
            string[] arr = CodeSerial.Split(',');
            string code = "";
            int randValue = -1;

            //unchecked((int)DateTime.Now.Ticks)
            Random rand = new Random(GetNewSeed());

            for (int i = 0; i < len; i++)
            {
                randValue = rand.Next(0, arr.Length - 1);
                code += arr[randValue];
            }

            return code;
        }
        /// <summary>
        /// 创建验证码
        /// </summary>
        /// <returns></returns>
        public string GetVerifyCode()
        {
            return GetVerifyCode(this.Length);
        }
        /// <summary>
        /// 使用RNGCryptoServiceProvider 做种,可以在一秒内产生的随机数重复率非常
        /// 的低,对于以往使用时间做种的方法是个升级
        /// </summary>
        /// <returns></returns>
        public static int GetNewSeed()
        {
            byte[] rndBytes = new byte[4];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(rndBytes);
            return BitConverter.ToInt32(rndBytes, 0);
        }
        #endregion

        #endregion
    }
    /// <summary>
    /// 验证码-简化版
    /// </summary>
    public class VerifyCodeSimpleHandler
    {
        #region 属性

        static int _length = 5;
        static int _fontSize = 18;
        static int _padding = 4;
        static Color _backgroundColor = Color.White;
        //static string[] _fonts = { "Arial", "Georgia", "Rosewood Std", "Ravie", "Courier" };
        //系统自带字体:Arial、Courier、MS Serif、Tahoma、Verdana、Comic Sans、MS Sans Serif、Symbol、Time New Roman、Impact、Lucida Console、Marlett、Modem、Samall Fonts、Webdings、Windings、Roman、MS-DOS CP437、script、SIMHEI、SimSun&NSimSun、Palatino、Linotype、Microsoft、MS。
        static string[] _fonts = { "Arial", "Tahoma", "Verdana", "Time New Roman", "Lucida Console" };
        static string[] _codeSerial = {
                                          "1,2,3,4,5,6,7,8,9",
                                          "a,b,c,d,e,f,g,h,i,j,k,m,n,p,q,r,s,t,u,v,w,x,y,z",
                                          "A,B,C,D,E,F,G,H,I,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z"
                                      };

        static string _customerCode;
        static VerifyCodeHardType _level = VerifyCodeHardType.数字大写字母;


        /// <summary>
        /// 验证码长度(默认5个验证码的长度)
        /// </summary>
        public static int Length
        {
            get { return _length; }
            set { _length = value; }
        }
        /// <summary>
        /// 验证码字体大小(默认18像素)
        /// </summary>
        public static int FontSize
        {
            get { return _fontSize; }
            set { _fontSize = value; }
        }
        /// <summary>
        /// 边框补(默认2像素)
        /// </summary>
        public static int Padding
        {
            get { return _padding; }
            set { _padding = value; }
        }
        /// <summary>
        /// 自定义背景色(默认白色)
        /// </summary>
        public static Color BackgroundColor
        {
            get { return _backgroundColor; }
            set { _backgroundColor = value; }
        }
        /// <summary>
        /// 设置背景颜色(#CCCCCC)
        /// </summary>
        public static string SetBackgroundColor
        {
            set { _backgroundColor = ColorTranslator.FromHtml(value); }
        }
        /// <summary>
        /// 自定义字体数组
        /// </summary>
        public static string[] Fonts
        {
            get { return _fonts; }
            set { _fonts = value; }
        }
        /// <summary>
        /// 用户自定验证字符串(使用逗号分隔)
        /// </summary>
        public static string CustomerCode
        {
            get { return _customerCode; }
            set { _customerCode = value; }
        }
        /// <summary>
        /// 随机码字符串序列(使用逗号分隔)
        /// </summary>
        static string GetCodeSerial
        {
            get
            {
                ///如果有自定验证码,则返回自定验证码
                if (!string.IsNullOrEmpty(CustomerCode)) return CustomerCode;

                string codeSerial = _codeSerial[0];

                switch (_level)
                {
                    case VerifyCodeHardType.小写字母:
                        codeSerial = _codeSerial[1];
                        break;
                    case VerifyCodeHardType.大写字母:
                        codeSerial = _codeSerial[2];
                        break;
                    case VerifyCodeHardType.大小写字母:
                        codeSerial = _codeSerial[1] + "," + _codeSerial[2];
                        break;
                    case VerifyCodeHardType.数字小写字母:
                        codeSerial = _codeSerial[0] + "," + _codeSerial[1];
                        break;
                    case VerifyCodeHardType.数字大写字母:
                        codeSerial = _codeSerial[0] + "," + _codeSerial[2];
                        break;
                    case VerifyCodeHardType.数字大小写字母:
                        codeSerial = _codeSerial[0] + "," + _codeSerial[1] + "," + _codeSerial[2];
                        break;
                    default:
                        break;
                }

                return codeSerial;
            }
        }
        /// <summary>
        /// 验证码难度(默认简单)
        /// </summary>
        public static VerifyCodeHardType VerifyCodeHardType
        {
            get { return _level; }
            set { _level = value; }
        }

        #endregion

        #region 实现
        /// <summary>
        /// 生成验证码
        /// </summary>
        /// <param name="key">保存到Session的Key</param>
        /// <returns></returns>
        public static byte[] CreateVerifyCode(ref string buildCode)
        {
            //生成验证码
            string code = BuildString();
            //生成图片
            Image img = BuildImage(code);

            //返回验证码
            buildCode = code;

            //将验证码图片转换为流
            using (img)
            {
                System.IO.MemoryStream ms = new System.IO.MemoryStream();//内存流
                img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);//将图片保存到流

                return ms.ToArray();//返回byte[]
            }
        }
        #endregion

        #region 辅助函数
        /// <summary>
        /// 生成验证码
        /// </summary>
        /// <param name="length">验证码长度</param>
        /// <returns>返回随机生成的验证码</returns>
        public static string BuildString(int length = 5)
        {
            if (length == 0)
            {
                length = Length;
            }

            string[] arr = GetCodeSerial.Split(',');

            string code = "";

            int randValue = -1;

            Random rand = new Random(unchecked((int)DateTime.Now.Ticks));

            for (int i = 0; i < length; i++)
            {
                randValue = rand.Next(0, arr.Length - 1);

                code += arr[randValue];
            }

            return code;
        }
        /// <summary>
        /// 生成校验码图片
        /// </summary>
        /// <param name="code">已经生成的随机码</param>
        /// <returns>位图</returns>
        public static Image BuildImage(string code)
        {
            int fSize = FontSize;
            int fWidth = fSize + Padding;

            int imageWidth = (int)(code.Length * fWidth) + 4 + Padding * 2 + 10;
            int imageHeight = fSize * 2 + Padding;

            //创建一个图片
            System.Drawing.Bitmap image = new System.Drawing.Bitmap(imageWidth, imageHeight);
            //GDI
            Graphics g = Graphics.FromImage(image);
            //填充背景色
            g.Clear(BackgroundColor);
            //随机
            Random rand = new Random();

            float left = rand.Next(10, 50), top = 0, top1 = 1, top2 = 1;

            int n1 = (imageHeight - FontSize - Padding * 2);
            int n2 = n1 / 4;
            top1 = n2;
            top2 = n2 * 2;

            Font font;
            Brush brush;

            int findex, fsindex;

            //随机字体和颜色的验证码字符
            for (int i = 0; i < code.Length; i++)
            {
                string codeText = code.Substring(i, 1);

                findex = rand.Next(Fonts.Length - 1);
                fsindex = rand.Next(5);

                font = new System.Drawing.Font(Fonts[findex], fSize, FontStyle.Regular);
                brush = new System.Drawing.SolidBrush(Color.Blue);
                SizeF fontSize = g.MeasureString(codeText, font);

                if (i % 2 == 1)
                {
                    top = top2;
                }
                else
                {
                    top = top1;
                }
                //写验证码
                g.DrawString(codeText, font, brush, left, top);
                //左侧坐标
                left += fontSize.Width / 2;
            }

            //画一个边框
            //g.DrawRectangle(new Pen(Color.Black, 0), 0, 0, image.Width - 1, image.Height - 1);
            //释放资源
            g.Dispose();
            //返回图片
            return image;
        }
        #endregion
    }
    /// <summary>
    /// 验证码困难
    /// </summary>
    public enum VerifyCodeHardType
    {
        数字,
        小写字母,
        大写字母,
        大小写字母,
        数字小写字母,
        数字大写字母,
        数字大小写字母
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MOZ-Soft

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值