好长时间没来了,发一个JAVA写的解析网站验证码的程序。(100分)

  • 主题发起人 woyaoying
  • 开始时间
W

woyaoying

Unregistered / Unconfirmed
GUEST, unregistred user!
/**
* 图片解析引擎,适合做网站验证码的分析。
* 首先必须载入样品,解析器将从左到右横向扫描,发现于样本的就自动记录。
* 当然本程序不适合样本不是唯一的,也就是说要识别的图片被缩放或者坐标变动和变形本程序无法进行这样的识别。
* 如果图片中的颜色变化非常大,此程序可能会有问题,当然了你可以选择一个标准的值做为转换成0,1矩阵的标准。
*
* 样本的制作:请将样本转换成灰度模式,只含有两色最好,当然了不转换我也帮你转换了。
*
*/
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.imageio.ImageIO;
public class ImageParser {
// ------------------------------------------------------------ Private Data
// 样本的矩阵
private static List swatches = null;
// 样本的值
private static List swatcheValues = null;
// 图片文件的矩阵化
private byte[][] targetColors;

// ------------------------------------------------------------ Test main method
public static void main(String[] args) {
// 加入样本与其样本对应的数值
String[] files = new String[10];
String[] values = new String[10];
for (int i = 0;
i < files.length;
i++){
files = &quot;D://workspace//SZXClientAPP//res//&quot;
+ i + &quot;.jpg&quot;;
values = String.valueOf(i);
}

ImageParser parse = new ImageParser(files, values);
long startime = System.currentTimeMillis();
try {
// 解析图片
System.out.println(parse.parseValue(&quot;D://workspace//SZXClientAPP//res//ValidateNum&quot;));
long sincetime = System.currentTimeMillis();
System.out.println(&quot;所花时间 = &quot;
+ (sincetime - startime));
} catch (Exception e) {
e.printStackTrace();
}
}
// ------------------------------------------------------------ Constructors
/**
* 载入所有样本路径与其样本对应的数值
*
* @param files
*/
public ImageParser(String[] files, String[] values) {
// 只允许样本创建一次即可
if (swatches == null && swatcheValues == null) {
int fileslength = files.length;
int valueslength = values.length;
if(fileslength != valueslength){
System.out.println(&quot;样本文件与样本数值不匹配!请重新设置!&quot;);
return;
}
swatches = new ArrayList(fileslength);
swatcheValues = new ArrayList(valueslength);
int i = 0;
try {
for (;
i < files.length;
i++) {
swatches.add(imageToMatrix(files));
swatcheValues.add(i, values);
}
} catch (Exception e) {
System.out.println(files + &quot;
can not be parsed&quot;);
e.printStackTrace();
}
}
}
public ImageParser() {
super();
if (swatches == null || swatcheValues == null) {
System.out.println(&quot;您未载入样本,请先载入样本!&quot;);
}
}
/**
* 解析图片的值
*
* @param parseFilePath
* 给出图片路径
* @return 返回字符串
* @throws Exception
*/
public String parseValue(String parseFilePath) throws Exception {
StringBuffer result = new StringBuffer();
targetColors = imageToMatrix(parseFilePath);
// printMatrix(targetColors);
int height = targetColors.length;
int targetWidth = targetColors[0].length;
int width = 0;
Iterator it = swatches.iterator();
while (it.hasNext()) {
byte[][] bytes = (byte[][]) it.next();
int templen = bytes[0].length;
if (templen > width)
width = templen;
}
// System.out.println(&quot;MaxWidth = &quot;
+ width);
// System.out.println(&quot;MaxHeight = &quot;
+ height);
int xTag = 0;
while ((xTag + width) < targetWidth) {
cout: {
Iterator itx = swatches.iterator();
int i = 0;
while (itx.hasNext()) {
byte[][] bytes = (byte[][]) itx.next();
byte[][] temp = splitMatrix(targetColors, xTag, 0, width, height);
// System.out.println(i++);
if (isMatrixInBigMatrix(bytes, temp)) {
xTag += width;
// System.out.println(&quot;new maxtrix: &quot;);
// printMatrix(temp);

result.append(swatcheValues.get(i));
break cout;
}
i++;
}
xTag++;
}
}
return result.toString();
}
// ------------------------------------------------------------ Private methods
/**
* 判断一个矩阵是否在另外的矩阵中
*
* @param source
* 源矩阵
* @param bigMatrix
* 大的矩阵
* @return 如果存在就返回 true
*/
private static final boolean isMatrixInBigMatrix(byte[][] source, byte[][] bigMatrix) {
if (source == bigMatrix)
return true;
if (source == null || bigMatrix == null)
return false;
if (source.length > bigMatrix.length)
return false;
try {
for (int i = 0;
i < source.length;
i++) {
if (source.length > bigMatrix.length)
return false;
}
} catch (ArrayIndexOutOfBoundsException e) {
return false;
}
int height = source.length;
int width = source[0].length;
int x = 0, y = 0;
int i = 0, j = 0;
int count = 0;
int comparecount = height * width;
for (;
i < bigMatrix.length - height + 1;
i++) {
for (j = 0;
j < bigMatrix.length - width + 1;
j++) {
cout: {
x = 0;
count = 0;
for (int k = i;
k < height + i;
k++) {
y = 0;
for (int l = j;
l < width + j;
l++) {
// System.out.println(&quot;bytes[&quot;
+ x + &quot;][&quot;
+ y + &quot;]&quot;
// + &quot;
= &quot;
+ source[x][y] + &quot;, &quot;
+ &quot;other[&quot;
// + k + &quot;][&quot;
+ l + &quot;] = &quot;
+ bigMatrix[k][l]);
if ((source[x][y] & bigMatrix[k][l]) == source[x][y]) {
count++;
} else
break cout;
y++;
}
x++;
}
// System.out.println(&quot;count = &quot;
+ count);
if (count == comparecount)
return true;
}
}
}
return false;
}
/**
* 切割矩阵
*
* @param source
* 源矩阵
* @param x
* X坐标
* @param y
* Y坐标
* @param width
* 矩阵的宽度
* @param height
* 矩阵的高度
* @return 切割后的矩阵
*/
private static final byte[][] splitMatrix(byte[][] source, int x, int y, int width, int height) {
byte[][] resultbytes = new byte[height][width];
for (int i = y, k = 0;
i < height + y;
i++, k++) {
for (int j = x, l = 0;
j < width + x;
j++, l++) {
resultbytes[k][l] = source[j];
// System.out.println(&quot;source[&quot;
+ i + &quot;][&quot;
+ j + &quot;]&quot;
+ &quot;
= &quot;
+
// source[j] + &quot;, &quot;
+ &quot;resultbytes[&quot;
// + k + &quot;][&quot;
+ l + &quot;] = &quot;
+ resultbytes[k][l]);
}
}
return resultbytes;
}
/**
* 图片转换成矩阵数组
*
* @param filePath
* 文件路径
* @return 返回矩阵
* @throws Exception
* 可能会抛出异常
*/
private byte[][] imageToMatrix(String filePath) throws Exception {
// 读入文件
Image image = ImageIO.read(new File(filePath));
int w = image.getWidth(null);
int h = image.getHeight(null);
BufferedImage src = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
src.getGraphics().drawImage(image, 0, 0, null);
byte[][] colors = new byte[h][w];
for (int i = 0;
i < h;
i++) {
for (int j = 0;
j < w;
j++) {
int rgb = src.getRGB(j, i);
// 像素进行灰度处理
String sRed = Integer.toHexString(rgb).substring(2, 4);
String sGreen = Integer.toHexString(rgb).substring(4, 6);
String sBlank = Integer.toHexString(rgb).substring(6, 8);
long ired = Math.round((Integer.parseInt(sRed, 16) * 0.3 + 0.5d));
long igreen = Math.round((Integer.parseInt(sGreen, 16) * 0.59 + 0.5d));
long iblank = Math.round((Integer.parseInt(sBlank, 16) * 0.11 + 0.5d));
long al = ired + igreen + iblank;
// if (al > 127)
// System.out.print(&quot;
&quot;
+ &quot;
&quot;);
// else
// System.out.print(&quot;
&quot;
+ &quot;1&quot;);
// System.out.print(&quot;
&quot;
+ (tempint > = maxint ? 0 : 1));
// System.out.println(&quot;tempInt = &quot;
+ tempint);
/* 将图像转换成0,1 */
// 此处的值可以将来修改成你所需要判断的值
colors[j] = (byte) (al > 127 ? 0 : 1);
}
// System.out.println();
}
return colors;
}
/**
* 打印矩阵
*
* @param matrix
*/
private static final void printMatrix(byte[][] matrix) {
for (int i = 0;
i < matrix.length;
i++) {
for (int j = 0;
j < matrix.length;
j++) {
if (matrix[j] == 0)
System.out.print(&quot;
&quot;);
else
System.out.print(&quot;
1&quot;);
}
System.out.println();
}
}
}
 
顶顶.
不错不错.
 
楼主你能具体说一下它能实现些什么功能吗?还有这个类怎么用啊? 谢谢!!
 
首先你应该对图片进行样本采集,然后将样本进行灰度处理,也就是变成黑白两色。
然后你就可以使用该类,对目标文件进行分析。具体怎么实现我觉得这个类非常清楚,就是将样本从左都有这么横向移动,比出一个来就九将坐标调整到下个位置。
 
hoho... 厉害的。 收藏之。。
 

Similar threads

I
回复
0
查看
735
import
I
I
回复
0
查看
583
import
I
I
回复
0
查看
875
import
I
顶部