用于验证码图片识别的类(C#源码)

   最近写了几个网站的验证码图片自动识别程序,尽管每个网站的验证码图片都不相同,识别的方法有所差别。但写得多了,也总结出不少相同之处。今天抽空封装出一个基础类来,发现可以很好地重复利用,编写不同的验证码识别程序,效率提高了不少。好东东不能独享,现放出来供大家共同研究,请网友们妥善用之。
        封装后的类使用很简单,针对不同的验证码,相应继承修改某些方法,即可简单几句代码就可以实现图片识别了:
            GrayByPixels(); //灰度处理
            GetPicValidByValue(128, 4); //得到有效空间
            Bitmap[] pics = GetSplitPics(4, 1);     //分割
            string code = GetSingleBmpCode(pics[i], 128);   //得到代码串

 

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Collections;
using  System.Drawing;
using  System.Drawing.Imaging;
using  System.Runtime.InteropServices;

namespace  BallotAiying2
{
    
class  UnCodebase
    {
        
public  Bitmap bmpobj;
        
public  UnCodebase(Bitmap pic)
        {
            bmpobj 
=   new  Bitmap(pic);     // 转换为Format32bppRgb
        }

        
/**/ ///   <summary>
        
///  根据RGB,计算灰度值
        
///   </summary>
        
///   <param name="posClr"> Color值 </param>
        
///   <returns> 灰度值,整型 </returns>
         private   int  GetGrayNumColor(System.Drawing.Color posClr)
        {
            
return  (posClr.R  *   19595   +  posClr.G  *   38469   +  posClr.B  *   7472 >>   16 ;
        }

        
/**/ ///   <summary>
        
///  灰度转换,逐点方式
        
///   </summary>
         public   void  GrayByPixels()
        {
            
for  ( int  i  =   0 ; i  <  bmpobj.Height; i ++ )
            {
                
for  ( int  j  =   0 ; j  <  bmpobj.Width; j ++ )
                {
                    
int  tmpValue  =  GetGrayNumColor(bmpobj.GetPixel(j, i));
                    bmpobj.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));
                }
            }
        }

        
/**/ ///   <summary>
        
///  去图形边框
        
///   </summary>
        
///   <param name="borderWidth"></param>
         public   void  ClearPicBorder( int  borderWidth)
        {
            
for  ( int  i  =   0 ; i  <  bmpobj.Height; i ++ )
            {
                
for  ( int  j  =   0 ; j  <  bmpobj.Width; j ++ )
                {
                    
if  (i  <  borderWidth  ||  j  <  borderWidth  ||  j  >  bmpobj.Width  -   1   -  borderWidth  ||  i  >  bmpobj.Height  -   1   -  borderWidth)
                        bmpobj.SetPixel(j, i, Color.FromArgb(
255 255 255 ));
                }
            }
        }

        
/**/ ///   <summary>
        
///  灰度转换,逐行方式
        
///   </summary>
         public   void  GrayByLine()
        {
            Rectangle rec 
=   new  Rectangle( 0 0 , bmpobj.Width, bmpobj.Height);
            BitmapData bmpData 
=  bmpobj.LockBits(rec, ImageLockMode.ReadWrite, bmpobj.PixelFormat); //  PixelFormat.Format32bppPArgb);
            
//     bmpData.PixelFormat = PixelFormat.Format24bppRgb;
            IntPtr scan0  =  bmpData.Scan0;
            
int  len  =  bmpobj.Width  *  bmpobj.Height;
            
int [] pixels  =   new   int [len];
            Marshal.Copy(scan0, pixels, 
0 , len);

            
// 对图片进行处理
             int  GrayValue  =   0 ;
            
for  ( int  i  =   0 ; i  <  len; i ++ )
            {
                GrayValue 
=  GetGrayNumColor(Color.FromArgb(pixels[i]));
                pixels[i] 
=  ( byte )(Color.FromArgb(GrayValue, GrayValue, GrayValue)).ToArgb();       // Color转byte
            }

            bmpobj.UnlockBits(bmpData);
        }

        
/**/ ///   <summary>
        
///  得到有效图形并调整为可平均分割的大小
        
///   </summary>
        
///   <param name="dgGrayValue"> 灰度背景分界值 </param>
        
///   <param name="CharsCount"> 有效字符数 </param>
        
///   <returns></returns>
         public   void  GetPicValidByValue( int  dgGrayValue,  int  CharsCount)
        {
            
int  posx1  =  bmpobj.Width;  int  posy1  =  bmpobj.Height;
            
int  posx2  =   0 int  posy2  =   0 ;
            
for  ( int  i  =   0 ; i  <  bmpobj.Height; i ++ )       // 找有效区
            {
                
for  ( int  j  =   0 ; j  <  bmpobj.Width; j ++ )
                {
                    
int  pixelValue  =  bmpobj.GetPixel(j, i).R;
                    
if  (pixelValue  <  dgGrayValue)      // 根据灰度值
                    {
                        
if  (posx1  >  j) posx1  =  j;
                        
if  (posy1  >  i) posy1  =  i;

                        
if  (posx2  <  j) posx2  =  j;
                        
if  (posy2  <  i) posy2  =  i;
                    };
                };
            };
            
//  确保能整除
             int  Span  =  CharsCount  -  (posx2  -  posx1  +   1 %  CharsCount;    // 可整除的差额数
             if  (Span  <  CharsCount)
            {
                
int  leftSpan  =  Span  /   2 ;     // 分配到左边的空列 ,如span为单数,则右边比左边大1
                 if  (posx1  >  leftSpan)
                    posx1 
=  posx1  -  leftSpan;
                
if  (posx2  +  Span  -  leftSpan  <  bmpobj.Width)
                    posx2 
=  posx2  +  Span  -  leftSpan;
            }
            
// 复制新图
            Rectangle cloneRect  =   new  Rectangle(posx1, posy1, posx2  -  posx1  +   1 , posy2  -  posy1  +   1 );
            bmpobj 
=  bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
        }
        
        
/**/ ///   <summary>
        
///  得到有效图形,图形为类变量
        
///   </summary>
        
///   <param name="dgGrayValue"> 灰度背景分界值 </param>
        
///   <param name="CharsCount"> 有效字符数 </param>
        
///   <returns></returns>
         public   void  GetPicValidByValue( int  dgGrayValue)
        {
            
int  posx1  =  bmpobj.Width;  int  posy1  =  bmpobj.Height;
            
int  posx2  =   0 int  posy2  =   0 ;
            
for  ( int  i  =   0 ; i  <  bmpobj.Height; i ++ )       // 找有效区
            {
                
for  ( int  j  =   0 ; j  <  bmpobj.Width; j ++ )
                {
                    
int  pixelValue  =  bmpobj.GetPixel(j, i).R;
                    
if  (pixelValue  <  dgGrayValue)      // 根据灰度值
                    {
                        
if  (posx1  >  j) posx1  =  j;
                        
if  (posy1  >  i) posy1  =  i;

                        
if  (posx2  <  j) posx2  =  j;
                        
if  (posy2  <  i) posy2  =  i;
                    };
                };
            };
            
// 复制新图
            Rectangle cloneRect  =   new  Rectangle(posx1, posy1, posx2  -  posx1  +   1 , posy2  -  posy1  +   1 );
            bmpobj 
=  bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
        }

        
/**/ ///   <summary>
        
///  得到有效图形,图形由外面传入
        
///   </summary>
        
///   <param name="dgGrayValue"> 灰度背景分界值 </param>
        
///   <param name="CharsCount"> 有效字符数 </param>
        
///   <returns></returns>
         public  Bitmap GetPicValidByValue(Bitmap singlepic,  int  dgGrayValue)
        {
            
int  posx1  =  singlepic.Width;  int  posy1  =  singlepic.Height;
            
int  posx2  =   0 int  posy2  =   0 ;
            
for  ( int  i  =   0 ; i  <  singlepic.Height; i ++ )       // 找有效区
            {
                
for  ( int  j  =   0 ; j  <  singlepic.Width; j ++ )
                {
                    
int  pixelValue  =  singlepic.GetPixel(j, i).R;
                    
if  (pixelValue  <  dgGrayValue)      // 根据灰度值
                    {
                        
if  (posx1  >  j) posx1  =  j;
                        
if  (posy1  >  i) posy1  =  i;

                        
if  (posx2  <  j) posx2  =  j;
                        
if  (posy2  <  i) posy2  =  i;
                    };
                };
            };
            
// 复制新图
            Rectangle cloneRect  =   new  Rectangle(posx1, posy1, posx2  -  posx1  +   1 , posy2  -  posy1  +   1 );
            
return  singlepic.Clone(cloneRect, singlepic.PixelFormat);
        }
        
        
/**/ ///   <summary>
        
///  平均分割图片
        
///   </summary>
        
///   <param name="RowNum"> 水平上分割数 </param>
        
///   <param name="ColNum"> 垂直上分割数 </param>
        
///   <returns> 分割好的图片数组 </returns>
         public  Bitmap [] GetSplitPics( int  RowNum, int  ColNum)
        {
            
if  (RowNum  ==   0   ||  ColNum  ==   0 )
                
return   null ;
            
int  singW  =  bmpobj.Width  /  RowNum;
            
int  singH  =  bmpobj.Height  /  ColNum;
            Bitmap [] PicArray
= new  Bitmap[RowNum * ColNum];

            Rectangle cloneRect;
            
for  ( int  i  =   0 ; i  <  ColNum; i ++ )       // 找有效区
            {
                
for  ( int  j  =   0 ; j  <  RowNum; j ++ )
                {
                    cloneRect 
=   new  Rectangle(j * singW, i * singH, singW , singH);
                    PicArray[i
* RowNum + j] = bmpobj.Clone(cloneRect, bmpobj.PixelFormat); // 复制小块图
                }
            }
            
return  PicArray;
        }

        
/**/ ///   <summary>
        
///  返回灰度图片的点阵描述字串,1表示灰点,0表示背景
        
///   </summary>
        
///   <param name="singlepic"> 灰度图 </param>
        
///   <param name="dgGrayValue"> 背前景灰色界限 </param>
        
///   <returns></returns>
         public   string  GetSingleBmpCode(Bitmap singlepic,  int  dgGrayValue)
        {
            Color piexl;
            
string  code  =   "" ;
            
for  ( int  posy  =   0 ; posy  <  singlepic.Height; posy ++ )
                
for  ( int  posx  =   0 ; posx  <  singlepic.Width; posx ++ )
                {
                    piexl 
=  singlepic.GetPixel(posx, posy);
                    
if  (piexl.R  <  dgGrayValue)     //  Color.Black )
                        code  =  code  +   " 1 " ;
                    
else
                        code 
=  code  +   " 0 " ;
                }
            
return  code;
        }
    }
}

 

你可能感兴趣的:(验证码)