概述C#代碼和驗(yàn)證碼圖片
最近寫了C#代碼和驗(yàn)證碼圖片自動(dòng)識(shí)別程序,盡管每個(gè)網(wǎng)站的驗(yàn)證碼圖片都不相同,識(shí)別的方法有所差別。但寫得多了,也總結(jié)出不少相同之處。今天抽空封裝出一個(gè)基礎(chǔ)類來,發(fā)現(xiàn)可以很好地重復(fù)利用,編寫不同的驗(yàn)證碼識(shí)別程序,效率提高了不少。好東東不能獨(dú)享,現(xiàn)放出來供大家共同研究,請(qǐng)網(wǎng)友們妥善用之。
封裝后的類使用很簡(jiǎn)單,針對(duì)不同的驗(yàn)證碼,相應(yīng)繼承修改某些方法,簡(jiǎn)單幾句實(shí)現(xiàn)C#代碼和驗(yàn)證碼圖片識(shí)別:
- GrayByPixels();//灰度處理
- GetPicValidByValue(128,4);//得到有效空間
- Bitmap[]pics=GetSplitPics(4,1);//分割
- stringcode=GetSingleBmpCode(pics[i],128);//得到代碼串
具體使用,請(qǐng)參見我做的例子:
- usingSystem;
- usingSystem.Collections.Generic;
- usingSystem.Text;
- usingSystem.Collections;
- usingSystem.Drawing;
- usingSystem.Drawing.Imaging;
- usingSystem.Runtime.InteropServices;
- namespaceBallotAiying2
- {
- classUnCodebase
- {
- publicBitmapbmpobj;
- publicUnCodebase(Bitmappic)
- {
- bmpobj=newBitmap(pic);//轉(zhuǎn)換為Format32bppRgb
- }
- /**////<summary>
- ///根據(jù)RGB,計(jì)算灰度值
- ///</summary>
- ///<paramnameparamname="posClr">Color值</param>
- ///<returns>灰度值,整型</returns>
- privateintGetGrayNumColor(System.Drawing.ColorposClr)
- {
- return(posClr.R*19595+posClr.G*38469+posClr.B*7472)>>16;
- }
- /**////<summary>
- ///灰度轉(zhuǎn)換,逐點(diǎn)方式
- ///</summary>
- publicvoidGrayByPixels()
- {
- for(inti=0;i<bmpobj.Height;i++)
- {
- for(intj=0;j<bmpobj.Width;j++)
- {
- inttmpValue=GetGrayNumColor(bmpobj.GetPixel(j,i));
- bmpobj.SetPixel(j,i,Color.FromArgb(tmpValue,tmpValue,tmpValue));
- }
- }
- }
- /**////<summary>
- ///去圖形邊框
- ///</summary>
- ///<paramnameparamname="borderWidth"></param>
- publicvoidClearPicBorder(intborderWidth)
- {
- for(inti=0;i<bmpobj.Height;i++)
- {
- for(intj=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>
- ///灰度轉(zhuǎn)換,逐行方式
- ///</summary>
- publicvoidGrayByLine()
- {
- Rectanglerec=newRectangle(0,0,bmpobj.Width,bmpobj.Height);
- BitmapDatabmpData=bmpobj.LockBits(rec,ImageLockMode.ReadWrite,bmpobj.PixelFormat);
//PixelFormat.Format32bppPArgb);- //bmpData.PixelFormat=PixelFormat.Format24bppRgb;
- IntPtrscan0=bmpData.Scan0;
- intlen=bmpobj.Width*bmpobj.Height;
- int[]pixels=newint[len];
- Marshal.Copy(scan0,pixels,0,len);
- //對(duì)圖片進(jìn)行處理
- intGrayValue=0;
- for(inti=0;i<len;i++)
- {
- GrayValue=GetGrayNumColor(Color.FromArgb(pixels[i]));
- pixels[i]=(byte)(Color.FromArgb(GrayValue,GrayValue,GrayValue)).ToArgb();//Color轉(zhuǎn)byte
- }
- bmpobj.UnlockBits(bmpData);
- }
- /**////<summary>
- ///得到有效圖形并調(diào)整為可平均分割的大小
- ///</summary>
- ///<paramnameparamname="dgGrayValue">灰度背景分界值</param>
- ///<paramnameparamname="CharsCount">有效字符數(shù)</param>
- ///<returns></returns>
- publicvoidGetPicValidByValue(intdgGrayValue,intCharsCount)
- {
- intposx1=bmpobj.Width;intposy1=bmpobj.Height;
- intposx2=0;intposy2=0;
- for(inti=0;i<bmpobj.Height;i++)//找有效區(qū)
- {
- for(intj=0;j<bmpobj.Width;j++)
- {
- intpixelValue=bmpobj.GetPixel(j,i).R;
- if(pixelValue<dgGrayValue)//根據(jù)灰度值
- {
- if(posx1>j)posx1=j;
- if(posy1>i)posy1=i;
- if(posx2<j)posx2=j;
- if(posy2<i)posy2=i;
- };
- };
- };
- //確保能整除
- intSpan=CharsCount-(posx2-posx1+1)%CharsCount;//可整除的差額數(shù)
- if(Span<CharsCount)
- {
- intleftSpan=Span/2;//分配到左邊的空列,如span為單數(shù),則右邊比左邊大1
- if(posx1>leftSpan)
- posx1posx1=posx1-leftSpan;
- if(posx2+Span-leftSpan<bmpobj.Width)
- posx2posx2=posx2+Span-leftSpan;
- }
- //復(fù)制新圖
- RectanglecloneRect=newRectangle(posx1,posy1,posx2-posx1+1,posy2-posy1+1);
- bmpobjbmpobj=bmpobj.Clone(cloneRect,bmpobj.PixelFormat);
- }
- /**////<summary>
- ///得到有效圖形,圖形為類變量
- ///</summary>
- ///<paramnameparamname="dgGrayValue">灰度背景分界值</param>
- ///<paramnameparamname="CharsCount">有效字符數(shù)</param>
- ///<returns></returns>
- publicvoidGetPicValidByValue(intdgGrayValue)
- {
- intposx1=bmpobj.Width;intposy1=bmpobj.Height;
- intposx2=0;intposy2=0;
- for(inti=0;i<bmpobj.Height;i++)//找有效區(qū)
- {
- for(intj=0;j<bmpobj.Width;j++)
- {
- intpixelValue=bmpobj.GetPixel(j,i).R;
- if(pixelValue<dgGrayValue)//根據(jù)灰度值
- {
- if(posx1>j)posx1=j;
- if(posy1>i)posy1=i;
- if(posx2<j)posx2=j;
- if(posy2<i)posy2=i;
- };
- };
- };
- //復(fù)制新圖
- RectanglecloneRect=newRectangle(posx1,posy1,posx2-posx1+1,posy2-posy1+1);
- bmpobjbmpobj=bmpobj.Clone(cloneRect,bmpobj.PixelFormat);
- }
- /**////<summary>
- ///得到有效圖形,圖形由外面?zhèn)魅?
- ///</summary>
- ///<paramnameparamname="dgGrayValue">灰度背景分界值</param>
- ///<paramnameparamname="CharsCount">有效字符數(shù)</param>
- ///<returns></returns>
- publicBitmapGetPicValidByValue(Bitmapsinglepic,intdgGrayValue)
- {
- intposx1=singlepic.Width;intposy1=singlepic.Height;
- intposx2=0;intposy2=0;
- for(inti=0;i<singlepic.Height;i++)//找有效區(qū)
- {
- for(intj=0;j<singlepic.Width;j++)
- {
- intpixelValue=singlepic.GetPixel(j,i).R;
- if(pixelValue<dgGrayValue)//根據(jù)灰度值
- {
- if(posx1>j)posx1=j;
- if(posy1>i)posy1=i;
- if(posx2<j)posx2=j;
- if(posy2<i)posy2=i;
- };
- };
- };
- //復(fù)制新圖
- RectanglecloneRect=newRectangle(posx1,posy1,posx2-posx1+1,posy2-posy1+1);
- returnsinglepic.Clone(cloneRect,singlepic.PixelFormat);
- }
- /**////<summary>
- ///平均分割圖片
- ///</summary>
- ///<paramnameparamname="RowNum">水平上分割數(shù)</param>
- ///<paramnameparamname="ColNum">垂直上分割數(shù)</param>
- ///<returns>分割好的圖片數(shù)組</returns>
- publicBitmap[]GetSplitPics(intRowNum,intColNum)
- {
- if(RowNum==0||ColNum==0)
- returnnull;
- intsingW=bmpobj.Width/RowNum;
- intsingH=bmpobj.Height/ColNum;
- Bitmap[]PicArray=newBitmap[RowNum*ColNum];
- RectanglecloneRect;
- for(inti=0;i<ColNum;i++)//找有效區(qū)
- {
- for(intj=0;j<RowNum;j++)
- {
- cloneRect=newRectangle(j*singW,i*singH,singW,singH);
- PicArray[i*RowNum+j]=bmpobj.Clone(cloneRect,bmpobj.PixelFormat);//復(fù)制小塊圖
- }
- }
- returnPicArray;
- }
- /**////<summary>
- ///返回灰度圖片的點(diǎn)陣描述字串,1表示灰點(diǎn),0表示背景
- ///</summary>
- ///<paramnameparamname="singlepic">灰度圖</param>
- ///<paramnameparamname="dgGrayValue">背前景灰色界限</param>
- ///<returns></returns>
- publicstringGetSingleBmpCode(Bitmapsinglepic,intdgGrayValue)
- {
- Colorpiexl;
- stringcode="";
- for(intposy=0;posy<singlepic.Height;posy++)
- for(intposx=0;posx<singlepic.Width;posx++)
- {
- piexl=singlepic.GetPixel(posx,posy);
- if(piexl.R<dgGrayValue)//Color.Black)
- codecode=code+"1";
- else
- codecode=code+"0";
- }
- returncode;
- }
- }
- }
以上介紹C#代碼和驗(yàn)證碼圖片
【編輯推薦】