一个图片验证码的实现

其实实现一个图片验证码并不是什么难的问题,主要讲究的时验证的实现上如何提高程序的识别难度.所以在实现过程参考了一下google的做法,由于数字或字母适当重叠对人自身识别并不成什么问题,但对于计算增加的难度相对来说就比较高些了.如果感觉难度不大可以调整一下程序让让字母之间紧靠的近一点,也可适当地加下曲线来让分析上更难.不过做得太过的话,估计人自己都搞不清楚了:)

验证码效果

 

具体实现代码

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;

namespace Smark.ImageNumber
{
    /// 
    /// Copyright © henryfan 2012		 
    /// Email:	henryfan@msn.com	
    /// HomePage:	http://www.ikende.com		
    /// CreateTime:	2012/10/23 21:18:29
    /// 
    public class Generator
    {
        const string VALUE = "123456789";

        private static Dictionary mCharImages = new Dictionary(26);

        private static Image mLine;

        private static Random mRam = new Random();

        public static string GeneratorCode()
        {
            string code = "";
            for (int i = 0; i < 4; i++)
            {
                code += VALUE.Substring(GetRamValue() % VALUE.Length, 1);
            }
            return code;

        }

        static int GetRamValue()
        {

            return mRam.Next();
        }

        public static Image GetImage(string code)
        {
            Bitmap tmpImg = new Bitmap(100, 40);
            using (Graphics e = Graphics.FromImage(tmpImg))
            {

                int offset = 2;

                e.FillRectangle(new SolidBrush(Color.White), 0, 0, 200, 60);

                List items = new List();
                foreach (char key in code)
                {
                    items.Add(GetGeneratorItem(key));
                }
                for (int i = 0; i < items.Count; i++)
                {
                    if (i > 0)
                    {
                        if ((items[i].Value < 0 && items[i - 1].Value > 0) || (items[i].Value > 0 && items[i - 1].Value > 0)
                            || (items[i].Value < 0 && items[i - 1].Value < 0))
                            offset += 12;

                        else
                            offset += 18;
                    }
                    using (Image img = items[i].DrawImage())
                    {
                        if (Math.Abs(items[i].Value) > 20)
                            e.DrawImage(img, offset, 6);
                        else if (Math.Abs(items[i].Value) > 20)
                            e.DrawImage(img, offset, 4);
                        else
                            e.DrawImage(img, offset, 2);
                    }

                }


            }
            return tmpImg;
        }

        public static System.Collections.IEnumerable GetKeys
        {
            get
            {
                return mCharImages.Keys;
            }
        }

        private static GeneratorItem GetGeneratorItem(char key)
        {
            GeneratorItem item = new GeneratorItem();
            int value = GetRamValue() % 25;
            if (value < 10)
                value = 10;
            if (GetRamValue() % 2 == 0)
                value = -value;
            item.Value = value;
            item.Key = key;
            return item;
        }

        class GeneratorItem
        {
            public int Value { get; set; }
            public char Key { get; set; }
            public Image DrawImage()
            {
                Bitmap tmpImg = new Bitmap(50, 50);
                using (Graphics e = Graphics.FromImage(tmpImg))
                {
                    e.RotateTransform(Value, System.Drawing.Drawing2D.MatrixOrder.Append);
                    e.DrawImage(mCharImages[Key], 0, 0);
                    e.Flush();
                }
                return tmpImg;
            }
        }

        static Generator()
        {

            HatchBrush sb = new HatchBrush(HatchStyle.Percent40, Color.Black, Color.Black);

            foreach (char item in VALUE)
            {

                Bitmap bmp = new Bitmap(50, 50);
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.DrawString(new string(new char[] { item }), new Font("宋体", 24, FontStyle.Italic), sb, 2, 2);
                }
                mCharImages[item]= bmp;
            }

            mLine = new Bitmap(60, 4);
            using (Graphics g = Graphics.FromImage(mLine))
            {
                g.FillRectangle(sb, 0, 0, 60, 3);
            }

        }
    }
}
posted @ 2012-10-27 11:51  beetlex  阅读(3748)  评论(10编辑  收藏  举报