天天看點

關于驗證碼識别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

本頁版權歸作者和部落格園所有,歡迎轉載,但未經作者同意必須保留此段聲明,

且在文章頁面明顯位置給出原文連結,否則保留追究法律責任的權利