天天看点

关于验证码识别2

 最近写了几个网站的验证码图片自动识别程序,尽管每个网站的验证码图片都不相同,识别的方法有所差别。但写得多了,也总结出不少相同之处。今天抽空封装出一个基础类来,发现可以很好地重复利用,编写不同的验证码识别程序,效率提高了不少。好东东不能独享,现放出来供大家共同研究,请网友们妥善用之。

        封装后的类使用很简单,针对不同的验证码,相应继承修改某些方法,即可简单几句代码就可以实现图片识别了:

            GrayByPixels(); //灰度处理

            GetPicValidByValue(128, 4); //得到有效空间

            Bitmap[] pics = GetSplitPics(4, 1);     //分割

            string code = GetSingleBmpCode(pics[i], 128);   //得到代码串

            具体使用,请参见我做的例子:

关于验证码识别2

using System;

关于验证码识别2

using System.Collections.Generic;

关于验证码识别2

using System.Text;

关于验证码识别2

using System.Collections;

关于验证码识别2

using System.Drawing;

关于验证码识别2

using System.Drawing.Imaging;

关于验证码识别2

using System.Runtime.InteropServices;

关于验证码识别2
关于验证码识别2

namespace BallotAiying2

关于验证码识别2

{

关于验证码识别2

    class UnCodebase

关于验证码识别2

    {

关于验证码识别2

        public Bitmap bmpobj;

关于验证码识别2

        public UnCodebase(Bitmap pic)

关于验证码识别2

        {

关于验证码识别2

            bmpobj = new Bitmap(pic);    //转换为Format32bppRgb

关于验证码识别2

        }

关于验证码识别2
关于验证码识别2

        /// <summary>

关于验证码识别2

        /// 根据RGB,计算灰度值

关于验证码识别2

        /// </summary>

关于验证码识别2

        /// <param name="posClr">Color值</param>

关于验证码识别2

        /// <returns>灰度值,整型</returns>

关于验证码识别2

        private int GetGrayNumColor(System.Drawing.Color posClr)

关于验证码识别2
关于验证码识别2

            return (posClr.R * 19595 + posClr.G * 38469 + posClr.B * 7472) >> 16;

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

        /// 灰度转换,逐点方式

关于验证码识别2
关于验证码识别2

        public void GrayByPixels()

关于验证码识别2
关于验证码识别2

            for (int i = 0; i < bmpobj.Height; i++)

关于验证码识别2

            {

关于验证码识别2

                for (int j = 0; j < bmpobj.Width; j++)

关于验证码识别2

                {

关于验证码识别2

                    int tmpValue = GetGrayNumColor(bmpobj.GetPixel(j, i));

关于验证码识别2

                    bmpobj.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));

关于验证码识别2

                }

关于验证码识别2

            }

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

        /// 去图形边框

关于验证码识别2
关于验证码识别2

        /// <param name="borderWidth"></param>

关于验证码识别2

        public void ClearPicBorder(int borderWidth)

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

                    if (i < borderWidth || j < borderWidth || j > bmpobj.Width - 1 - borderWidth || i > bmpobj.Height - 1 - borderWidth)

关于验证码识别2

                        bmpobj.SetPixel(j, i, Color.FromArgb(255, 255, 255));

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

        /// 灰度转换,逐行方式

关于验证码识别2
关于验证码识别2

        public void GrayByLine()

关于验证码识别2
关于验证码识别2

            Rectangle rec = new Rectangle(0, 0, bmpobj.Width, bmpobj.Height);

关于验证码识别2

            BitmapData bmpData = bmpobj.LockBits(rec, ImageLockMode.ReadWrite, bmpobj.PixelFormat);// PixelFormat.Format32bppPArgb);

关于验证码识别2

            //    bmpData.PixelFormat = PixelFormat.Format24bppRgb;

关于验证码识别2

            IntPtr scan0 = bmpData.Scan0;

关于验证码识别2

            int len = bmpobj.Width * bmpobj.Height;

关于验证码识别2

            int[] pixels = new int[len];

关于验证码识别2

            Marshal.Copy(scan0, pixels, 0, len);

关于验证码识别2
关于验证码识别2

            //对图片进行处理

关于验证码识别2

            int GrayValue = 0;

关于验证码识别2

            for (int i = 0; i < len; i++)

关于验证码识别2
关于验证码识别2

                GrayValue = GetGrayNumColor(Color.FromArgb(pixels[i]));

关于验证码识别2

                pixels[i] = (byte)(Color.FromArgb(GrayValue, GrayValue, GrayValue)).ToArgb();      //Color转byte

关于验证码识别2
关于验证码识别2
关于验证码识别2

            bmpobj.UnlockBits(bmpData);

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

        /// 得到有效图形并调整为可平均分割的大小

关于验证码识别2
关于验证码识别2

        /// <param name="dgGrayValue">灰度背景分界值</param>

关于验证码识别2

        /// <param name="CharsCount">有效字符数</param>

关于验证码识别2

        /// <returns></returns>

关于验证码识别2

        public void GetPicValidByValue(int dgGrayValue, int CharsCount)

关于验证码识别2
关于验证码识别2

            int posx1 = bmpobj.Width; int posy1 = bmpobj.Height;

关于验证码识别2

            int posx2 = 0; int posy2 = 0;

关于验证码识别2

            for (int i = 0; i < bmpobj.Height; i++)      //找有效区

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

                    int pixelValue = bmpobj.GetPixel(j, i).R;

关于验证码识别2

                    if (pixelValue < dgGrayValue)     //根据灰度值

关于验证码识别2

                    {

关于验证码识别2

                        if (posx1 > j) posx1 = j;

关于验证码识别2

                        if (posy1 > i) posy1 = i;

关于验证码识别2
关于验证码识别2

                        if (posx2 < j) posx2 = j;

关于验证码识别2

                        if (posy2 < i) posy2 = i;

关于验证码识别2

                    };

关于验证码识别2

                };

关于验证码识别2

            };

关于验证码识别2

            // 确保能整除

关于验证码识别2

            int Span = CharsCount - (posx2 - posx1 + 1) % CharsCount;   //可整除的差额数

关于验证码识别2

            if (Span < CharsCount)

关于验证码识别2
关于验证码识别2

                int leftSpan = Span / 2;    //分配到左边的空列 ,如span为单数,则右边比左边大1

关于验证码识别2

                if (posx1 > leftSpan)

关于验证码识别2

                    posx1 = posx1 - leftSpan;

关于验证码识别2

                if (posx2 + Span - leftSpan < bmpobj.Width)

关于验证码识别2

                    posx2 = posx2 + Span - leftSpan;

关于验证码识别2
关于验证码识别2

            //复制新图

关于验证码识别2

            Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);

关于验证码识别2

            bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

        /// 得到有效图形,图形为类变量

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

        public void GetPicValidByValue(int dgGrayValue)

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

        /// 得到有效图形,图形由外面传入

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

        public Bitmap GetPicValidByValue(Bitmap singlepic, int dgGrayValue)

关于验证码识别2
关于验证码识别2

            int posx1 = singlepic.Width; int posy1 = singlepic.Height;

关于验证码识别2
关于验证码识别2

            for (int i = 0; i < singlepic.Height; i++)      //找有效区

关于验证码识别2
关于验证码识别2

                for (int j = 0; j < singlepic.Width; j++)

关于验证码识别2
关于验证码识别2

                    int pixelValue = singlepic.GetPixel(j, i).R;

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

            return singlepic.Clone(cloneRect, singlepic.PixelFormat);

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

        /// 平均分割图片

关于验证码识别2
关于验证码识别2

        /// <param name="RowNum">水平上分割数</param>

关于验证码识别2

        /// <param name="ColNum">垂直上分割数</param>

关于验证码识别2

        /// <returns>分割好的图片数组</returns>

关于验证码识别2

        public Bitmap [] GetSplitPics(int RowNum,int ColNum)

关于验证码识别2
关于验证码识别2

            if (RowNum == 0 || ColNum == 0)

关于验证码识别2

                return null;

关于验证码识别2

            int singW = bmpobj.Width / RowNum;

关于验证码识别2

            int singH = bmpobj.Height / ColNum;

关于验证码识别2

            Bitmap [] PicArray=new Bitmap[RowNum*ColNum];

关于验证码识别2
关于验证码识别2

            Rectangle cloneRect;

关于验证码识别2

            for (int i = 0; i < ColNum; i++)      //找有效区

关于验证码识别2
关于验证码识别2

                for (int j = 0; j < RowNum; j++)

关于验证码识别2
关于验证码识别2

                    cloneRect = new Rectangle(j*singW, i*singH, singW , singH);

关于验证码识别2

                    PicArray[i*RowNum+j]=bmpobj.Clone(cloneRect, bmpobj.PixelFormat);//复制小块图

关于验证码识别2
关于验证码识别2
关于验证码识别2

            return PicArray;

关于验证码识别2
关于验证码识别2
关于验证码识别2
关于验证码识别2

        /// 返回灰度图片的点阵描述字串,1表示灰点,0表示背景

关于验证码识别2
关于验证码识别2

        /// <param name="singlepic">灰度图</param>

关于验证码识别2

        /// <param name="dgGrayValue">背前景灰色界限</param>

关于验证码识别2
关于验证码识别2

        public string GetSingleBmpCode(Bitmap singlepic, int dgGrayValue)

关于验证码识别2
关于验证码识别2

            Color piexl;

关于验证码识别2

            string code = "";

关于验证码识别2

            for (int posy = 0; posy < singlepic.Height; posy++)

关于验证码识别2

                for (int posx = 0; posx < singlepic.Width; posx++)

关于验证码识别2
关于验证码识别2

                    piexl = singlepic.GetPixel(posx, posy);

关于验证码识别2

                    if (piexl.R < dgGrayValue)    // Color.Black )

关于验证码识别2

                        code = code + "1";

关于验证码识别2

                    else

关于验证码识别2

                        code = code + "0";

关于验证码识别2
关于验证码识别2

            return code;

关于验证码识别2
关于验证码识别2

    }

关于验证码识别2

}

关于验证码识别2

QQ:519841366

本页版权归作者和博客园所有,欢迎转载,但未经作者同意必须保留此段声明,

且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利