C#彩色扭曲验证码

本文介绍了一个在生产环境中使用的C#验证码生成类,集成了多种增强验证码安全性的特性,如背景噪点、曲线、直线、文字扭曲、调暗和模糊处理,有效防止了自动识别。通过示例图片展示效果,详细解析了验证码的实现过程。
摘要由CSDN通过智能技术生成

该验证码生成类集合了网上大部分的验证码生成类的精华,并多次改进,现在已经形成了可在生产环节中使用的验证码。

该验证码加入了背景噪点,背景噪点曲线和直线,背景噪点文字以及扭曲,调暗,模糊等。完全可以实现防识别。

按照国际惯例先贴张效果图吧:

    #region 验证码生成类
        /// <summary>
        /// 验证码生成类
        /// </summary>
        public class ValidateCode
        {
            #region 定义和初始化配置字段
            //用户存取验证码字符串
            public string validationCode = String.Empty;
            //生成的验证码字符串
            public char[] chars = null;
            /// <summary>
            /// 获取系统生成的随机验证码
            /// </summary>
            public String ValidationCode
            {
                get { return validationCode; }
            }
            private Int32 validationCodeCount = 4;
            /// <summary>
            /// 获取和设置验证码字符串的长度
            /// </summary>
            public Int32 ValidationCodeCount
            {
                get { return validationCodeCount; }
                set { validationCodeCount = value; }
            }
            Graphics dc = null;
            private int bgWidth = 130;
            /// <summary>
            /// 验证码的宽度,默认为80
            /// </summary>
            public Int32 Width
            {
                get { return bgWidth; }
                set { bgWidth = value; }
            }

            private int bgHeight = 40;
            /// <summary>
            /// 验证码的高度,默认为40
            /// </summary>
            public Int32 Height
            {
                get { return bgHeight; }
                set { bgHeight = value; }
            }
            /* private string[] fontFace = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
             /// <summary>
             /// 验证码字体列表,默认为{ "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" }
             /// </summary>
             public String[] FontFace
             {
                 get { return fontFace; }
                 set { fontFace = value; }
             }*/

            private int fontMinSize = 20;
            /// <summary>
            /// 验证码字体的最小值,默认为15,建议不小于15像素
            /// </summary>
            public Int32 FontMinSize
            {
                get { return fontMinSize; }
                set { fontMinSize = value; }
            }
            private Int32 fontMaxSize = 25;
            /// <summary>
            /// 验证码字体的最大值,默认为20
            /// </summary>
            public Int32 FontMaxSize
            {
                get { return fontMaxSize; }
                set { fontMaxSize = value; }
            }
            private Color[] fontColor = { };
            /// <summary>
            /// 验证码字体的颜色,默认为系统自动生成字体颜色
            /// </summary>
            public Color[] FontColor
            {
                get { return fontColor; }
                set { fontColor = value; }
            }
            private Color backColor = Color.FromArgb(243, 255, 255);
            /// <summary>
            /// 验证码的背景色,默认为Color.FromArgb(243, 251, 254)
            /// </summary>
            public Color BackgroundColor
            {
                get { return backColor; }
                set { backColor = value; }
            }
            private Int32 bezierCount = 3;
            /// <summary>
            /// 贝塞尔曲线的条数,默认为3条
            /// </summary>
            public Int32 BezierCount
            {
                get { return bezierCount; }
                set { bezierCount = value; }
            }
            private Int32 lineCount = 3;
            /// <summary>
            /// 直线条数,默认为3条
            /// </summary>
            public Int32 LineCount
            {
                get { return lineCount; }
                set { lineCount = value; }
            }
            Random random = new Random();

            private String charCollection = "2,3,4,5,6,7,8,9,a,s,d,f,g,h,z,c,v,b,n,m,k,q,w,e,r,t,y,u,p,A,S,D,F,G,H,Z,C,V,B,N,M,K,Q,W,E,R,T,Y,U,P"; //定义验证码字符及出现频次 ,避免出现0 o j i l 1 x;  
            /// <summary>
            /// 随机字符串列表,请使用英文状态下的逗号分隔。
            /// </summary>
            public String CharCollection
            {
                get { return charCollection; }
                set { charCollection = value; }
            }
            private Int32 intCount = 4;
            /// <summary>
            /// 验证码字符串个数,默认为4个字符
            /// </summary>
            public Int32 IntCount
            {
                get { return intCount; }
                set { intCount = value; }
            }
            private Boolean isPixel = true;
            /// <summary>
            /// 是否添加噪点,默认添加,噪点颜色为系统随机生成。
            /// </summary>
            public Boolean IsPixel
            {
                get { return isPixel; }
                set { isPixel = value; }
            }
            private Boolean isRandString = true;
            /// <summary>
            /// 是否添加随机噪点字符串,默认添加
            /// </summary>
            public Boolean IsRandString
            {
                get { return isRandString; }
                set { isRandString = value; }
            }
            /// <summary>
            /// 随机背景字符串的个数
            /// </summary>
            public Int32 RandomStringCount
            {
                get;
                set;
            }
            private Int32 randomStringFontSize = 9;
            /// <summary>
            /// 随机背景字符串的大小
            /// </summary>
            public Int32 RandomStringFontSize
            {
                get { return randomStringFontSize; }
                set { randomStringFontSize = value; }
            }
            /// <summary>
            /// 是否对图片进行扭曲
            /// </summary>
            public Boolean IsTwist
            {
                get;
                set;
            }
            /// <summary>
            /// 边框样式
            /// </summary>
            public enum BorderStyle
            {
                /// <summary>
                /// 无边框
                /// </summary>
                None,
                /// <summary>
                /// 矩形边框
                /// </summary>
                Rectangle,
                /// <summary>
                /// 圆角边框
                /// </summary>
                RoundRectangle
            }
            private Int32 rotationAngle = 40;
            /// <summary>
            /// 验证码字符串随机转动的角度的最大值
            /// </summary>
            public Int32 RotationAngle
            {
                get { return rotationAngle; }
                set { rotationAngle = value; }
            }
            /// <summary>
            /// 设置或获取边框样式
            /// </summary>
            public BorderStyle Border
            {
                get;
                set;
            }
            private Point[] strPoint = null;


            private Double gaussianDeviation = 0;
            /// <summary>
            /// 对验证码图片进行高斯模糊的阀值,如果设置为0,则不对图片进行高斯模糊,该设置可能会对图片处理的性能有较大影响
            /// </summary>
            public Double GaussianDeviation
            {
                get { return gaussianDeviation; }
                set { gaussianDeviation = value; }
            }
            private Int32 brightnessValue = 0;
            /// <summary>
            /// 对图片进行暗度和亮度的调整,如果该值为0,则不调整。该设置会对图片处理性能有较大影响
            /// </summary>
            public Int32 BrightnessValue
            {
                get { return brightnessValue; }
                set { brightnessValue = value; }
            }
            #endregion
            /// <summary>
            /// 构造函数,用于初始化常用变量
            /// </summary>
            public void DrawValidationCode()
            {
                random = new Random(Guid.NewGuid().GetHashCode());
                strPoint = new Point[validationCodeCount + 1];
                if (gaussianDeviation < 0) gaussianDeviation = 0;
            }

            /// <summary>
            /// 生成验证码
            /// </summary>
            /// <param name="target">用于存储图片的一般字节序列</param>
            public byte[] CreateImage(string code)
            {
                MemoryStream target = new MemoryStream();
                Bitmap bit = new Bitmap(bgWidth + 1, bgHeight + 1);
                //写字符串
                dc = Graphics.FromImage(bit);
                dc.SmoothingMode = SmoothingMode.HighQuality;
                dc.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; ;
                dc.InterpolationMode = InterpolationMode.HighQualityBilinear;
                dc.CompositingQuality = CompositingQuality.HighQuality;

                try
                {
                    dc.Clear(Color.White);
                    DrawValidationCode();
                    dc.DrawImageUnscaled(DrawBackground(), 0, 0);
                    dc.DrawImageUnscaled(DrawRandomString(code), 0, 0);
                    //对图片文字进行扭曲
                    bit = AdjustRippleEffect(bit, 5);
                    //对图片进行高斯模糊
                    if (gaussianDeviation > 0)
                    {
                        Gaussian gau = new Gaussian();
                        bit = gau.FilterProcessImage(gaussianDeviation, bit);
                    }
                    //进行暗度和亮度处理
                    if (brightnessValue != 0)
                    {
                        //对图片进行调暗处理
                        bit = AdjustBrightness(bit, brightnessValue);
                    }
                    bit.Save(target, ImageFormat.Jpeg);
                    //输出图片流
                    return target.ToArray();
                }
                finally
                {
                    //brush.Dispose();
                    bit.Dispose();
                    dc.Dispose();
                }
            }

            #region 画验证码背景,例如,增加早点,添加曲线和直线等
            /// <summary>
            /// 画验证码背景,例如,增加早点,添加曲线和直线等
            /// </summary>
            /// <returns></returns>
            private Bitmap DrawBackground()
            {
                Bitmap bit = new Bitmap(bgWidth + 1, bgHeight + 1);
                Graphics g = Graphics.FromImage(bit);
                g.SmoothingMode = SmoothingMode.HighQuality;

                g.Clear(Color.White);
                Rectangle rectangle = new Rectangle(0, 0, bgWidth, bgHeight);
                Brush brush = new SolidBrush(backColor);
                g.FillRectangle(brush, rectangle);

                //画噪点
                if (isPixel)
                {
                    g.DrawImageUnscaled(DrawRandomPixel(30), 0, 0);
                }
                g.DrawImageUnscaled(DrawRandBgString(), 0, 0);


                //画曲线
                //g.DrawImageUnscaled(DrawRandomBezier(bezierCount), 0, 0);
                画直线
                //g.DrawImageUnscaled(DrawRandomLine(lineCount), 0, 0);

                //dc.DrawImageUnscaled(DrawStringline(), 0, 0);
                if (Border == BorderStyle.Rectangle)
                {
                    //绘制边框
                    g.DrawRectangle(new Pen(Color.FromArgb(90, 87, 46)), 0, 0, bgWidth, bgHeight);
                }
                else if (Border == BorderStyle.RoundRectangle)
                {
                    //画圆角
                    DrawRoundRectangle(g, rectangle, Color.FromArgb(90, 87, 46), 1, 3);
                }

                return bit;

            }
            #endregion

            #region 画正弦曲线
            private Bitmap DrawTwist(Bitmap bmp, Int32 tWidth, Int32 tHeight, float angle, Color color)
            {
                //为了方便查看效果,在这里我定义了一个常量。
                //它在定义数组的长度和for循环中都要用到。
                int size = bgWidth;

                double[] x = new double[size];
                Bitmap b = new Bitmap(bmp.Width, bmp.Height);
                b.MakeTransparent();
                Graphics graphics = Graphics.FromImage(b);
                Pen pen = new Pen(color);

                //画正弦曲线的横轴间距参数。建议所用的值应该是 正数且是2的倍数。
                //在这里采用2。
                int val = 2;

                float temp = 0.0f;

                //把画布下移100。为什么要这样做,只要你把这一句给注释掉,运行一下代码,
                //你就会明白是为什么?
                graphics.TranslateTransform(0, 100);
                graphics.SmoothingMode = SmoothingMode.HighQuality;
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                for (int i = 0; i < size; i++)
                {
                    //改变tWidth,实现正弦曲线宽度的变化。
                    //改tHeight,实现正弦曲线高度的变化。
                    x[i] = Math.Sin(2 * Math.PI * i / tWidth) * tHeight;

                    graphics.DrawLine(pen, i * val, temp, i * val + val / 2, (float)x[i]);
                    temp = (float)x[i];
                }
                graphics.RotateTransform(60, MatrixOrder.Prepend);

                //旋转图片
                // b = KiRotate(b, angle, Color.Transparent);
                return b;
            }
            #endregion

            #region 正弦曲线Wave扭曲图片
            /// <summary>
            /// 正弦曲线Wave扭曲图片
            /// </summary>
            /// <param name="srcBmp">图片路径</param>
            /// <param name="bXDir">如果扭曲则选择为True</param>
            /// <param name="dMultValue">波形的幅度倍数,越大扭曲的程度越高,一般为3</param>
            /// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
            /// <returns></returns>
            public Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
            {
                System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
                double PI2 = 6.283185307179586476925286766559;
               
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值