/** ImageCode.java
*
* Created on 2007年1月18日, 下午10:00
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.*/packagenet.bccn.hadeslee.programfan;importjava.awt.image.BufferedImage;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.StreamTokenizer;importjava.net.URL;importjavax.imageio.ImageIO;/*** 验证码识别程序
*@authorhadeslee*/publicclassImageCode {privateBufferedImage bi;privatestaticint[][][] model=newint[5][10][208];//静态初始化块static{
initNumModel();
}/*** Creates a new instance of ImageCode*/publicImageCode() {
initNumModel();
}publicString getNumber(InputStream is){try{
bi=ImageIO.read( is );finalStringBuffer sb=newStringBuffer();for(inti=0;i<4;i++){int[] data=this.getData(i);
sb.append(this.doCheck(data));
}returnsb.toString();
}catch(Exception exe){
exe.printStackTrace();return"";
}
}/*** 重载的方法,根据传进来的参数得到返回的字符串
*@parambi
*@return结果*/publicString getNumber(BufferedImage bi){try{this.bi=bi;
StringBuffer sb=newStringBuffer();for(inti=0;i<4;i++){int[] data=this.getData(i);
sb.append(this.doCheck(data));
}//System.out.println(sb.toString());returnsb.toString();
}catch(Exception exe){
exe.printStackTrace();return"";
}
}/*** 静态初始化方法,
* 用于初始化字模*/privatestaticvoidinitNumModel(){try{//System.out.println("初始化model");for(inti=0;i<10;i++){
StreamTokenizer st=newStreamTokenizer(newInputStreamReader(ImageCode.class.getResourceAsStream("/net/bccn/hadeslee/model/programfan_"+i+".mod")));
st.whitespaceChars('#','#');
st.whitespaceChars(',',',');
st.eolIsSignificant(false);
out:while(true){inttoken=st.nextToken();if(token==StreamTokenizer.TT_WORD){intwho=0;intindex=0;if(st.sval.equals("center")){
who=0;
}elseif(st.sval.equals("left")){
who=1;
}elseif(st.sval.equals("right")){
who=2;
}elseif(st.sval.equals("up")){
who=3;
}elseif(st.sval.equals("down")){
who=4;
}while(st.nextToken()==StreamTokenizer.TT_NUMBER){
model[who][i][index++]=(int)st.nval;
}
st.pushBack();
}elseif(token==StreamTokenizer.TT_EOF){breakout;
}
}
}
}catch(Exception exe){
exe.printStackTrace();
}//System.out.println("初始化结束model");}//通过传进来的字符串得到BufferedImage对象privateBufferedImage getBI(String url){try{returnImageIO.read(newURL(url));
}catch(IOException ex) {
ex.printStackTrace();returnnull;
}
}/**根据索引得到
*某一块的图像转为数组
*的文件*/privateint[] getData(intindex){
BufferedImage sub=bi.getSubimage(index*16,0,16,13);intiw=sub.getWidth();intih=sub.getHeight();int[] demo=newint[iw*ih];for(inti=0;i
demo[i*iw+j]=(sub.getRGB(j,i)==-1?0:1);
}
}returndemo;
}//根据传进来的数组,得到五个位置当中和差别最小的那个privateintgetMin(intwho,int[] demo){inttemp=208;for(inti=0;i<5;i++){intx=0;for(intj=0;j
x+=(model[i][who][j]==demo[j]?0:1);
}if(x
temp=x;
}
}//System.out.println("比对"+who+"最小值是"+temp);returntemp;
}//分析689或者0的方法,以免这几个数字混淆privateintget689(int[] demo,intorigin){booleanisLeft=false,isRight=false;inttemp=-1;if((demo[75]==1&&demo[90]==1)||(demo[76]==1&&demo[91]==1)||(demo[58]==1&&demo[74]==1&&demo[90]==1)||(demo[59]==1&&demo[75]==1&&demo[91]==1)||(demo[60]==1&&demo[76]==1&&demo[92]==1)||(demo[28]==1&&demo[44]==1&&demo[60]==1)||(demo[27]==1&&demo[43]==1&&demo[59]==1)){
isRight=true;
}if((demo[131]==1&&demo[147]==1)||(demo[132]==1&&demo[148]==1)||(demo[133]==1&&demo[149]==1)){
isLeft=true;
}if(isLeft&&isRight){
temp=8;
}elseif(isLeft){
temp=6;
}elseif(isRight){
temp=9;
}else{
temp=origin;
}if(temp==8&&(!((demo[103]==1&&demo[104]==1&&demo[105]==1&&demo[106]==1)||(demo[87]==1&&demo[88]==1&&demo[89]==1&&demo[90]==1)||(demo[103]+demo[104]+demo[105]+demo[106]+demo[87]+demo[88]+demo[89]+demo[90]>3)))){returntemp=0;
}returntemp;
}//比较传入的数据,返回最接近的值privateintdoCheck(int[] demo){intnumber=-1;inttemp=208;for(inti=0;i<10;i++){intx=this.getMin(i,demo);if(x
temp=x;
number=i;
}
}//System.out.println("===========================================");if(number==6||number==8||number==9){
number=this.get689(demo,number);
}returnnumber;
}
}