java 验证码图片处理类,为验证码识别做准备
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package snailocr.util;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
/**
*
* @author Administrator
*/
public class ImageTool {
private BufferedImage image;
private int width;
private int height;
/**
* 变图像为黑白色 提示: 黑白化之前最好灰色化以便得到好的灰度平均值,利于获得好的黑白效果
*
* @return
*/
public ImageTool changeToBlackWhiteImage() {
int avgGrayValue = getAvgValue();
int whitePoint = getWhitePoint(), blackPoint = getBlackPoint();
Color point;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
point = new Color(image.getRGB(j, i));
image.setRGB(j, i, (point.getRed() < avgGrayValue ? blackPoint : whitePoint));
}
}
return this;
}
/**
*
*
* @param whiteAreaPercent 过滤之后白色区域面积占整个图片面积的最小百分比
* @param removeLighter true:过滤比中值颜色轻的,false:过滤比中值颜色重的,一般都是true
* @return
*/
public ImageTool midddleValueFilter(int whiteAreaMinPercent, boolean removeLighter) {
int modify = 0;
int avg = getAvgValue();
Color point;
while (getWhitePercent() < whiteAreaMinPercent) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
point = new Color(image.getRGB(j, i));
if (removeLighter) {
if (((point.getRed() + point.getGreen() + point.getBlue()) / 3) > avg - modify) {
// System.out.println(((point.getRed() + point.getGreen() + point.getBlue()) / 3)+"--"+(avg - modify));
image.setRGB(j, i, getWhitePoint());
}
} else {
if (((point.getRed() + point.getGreen() + point.getBlue()) / 3) < avg + modify) {
// System.out.println(((point.getRed() + point.getGreen() + point.getBlue()) / 3)+"--"+(avg - modify));
image.setRGB(j, i, getWhitePoint());
}
}
}
}
modify++;
}
// System.out.println(getWhitePercent());
return this;
}
private int getWhitePercent() {
Color point;
int white = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
point = new Color(image.getRGB(j, i));
if (((point.getRed() + point.getGreen() + point.getBlue()) / 3) == 255) {
white++;
}
}
}
return (int) Math.ceil(((float) white * 100 / (width * height)));
}
/**
* @param 变图像为灰色 取像素点的rgb三色平均值作为灰度值
*
* @return
*/
public ImageTool changeToGrayImage() {
int gray;
Color point;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
point = new Color(image.getRGB(j, i));
gray = (point.getRed() + point.getGreen() + point.getBlue()) / 3;
image.setRGB(j, i, new Color(gray, gray, gray).getRGB());
}
}
return this;
}
/**
*
* 去除噪点和单点组成的干扰线 注意: 去除噪点之前应该对图像黑白化
*
* @param neighborhoodMinCount 每个点最少的邻居数
* @return
*/
public ImageTool removeBadBlock(int blockWidth, int blockHeight, int neighborhoodMinCount) {
int val;
int whitePoint = getWhitePoint();
int counter, topLeftXIndex, topLeftYIndex;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
//初始化邻居数为0
counter = 0;
topLeftXIndex = x - 1;
topLeftYIndex = y - 1;
//x1 y1是以x,y左上角点为顶点的矩形,该矩形包围在传入的矩形的外围,计算传入的矩形的有效邻居数目
if (isBlackBlock(x, y, blockWidth, blockHeight)) {//只有当块是全黑色才计算
for (int x1 = topLeftXIndex; x1 <= topLeftXIndex + blockWidth + 1; x1++) {
for (int y1 = topLeftYIndex; y1 <= topLeftYIndex + blockHeight + 1; y1++) {
//判断这个点是否存在
if (x1 < width && x1 >= 0 && y1 < height && y1 >= 0) {
//判断这个点是否是传入矩形的外围点
if (x1 == topLeftXIndex || x1 == topLeftXIndex + blockWidth + 1
|| y1 == topLeftYIndex || y1 == topLeftYIndex + blockHeight + 1) {
//这里假定图像已经被黑白化,取Red值认为不是0就是255
val = new Color(image.getRGB(x1, y1)).getRed();
// System.out.println(val + "--" + (centerVal));
//如果这个邻居是黑色,就把中心点的有效邻居数目加一
if (val == 0) {
counter++;
}
}
}
}
}
// System.out.println("-------------------");
// System.out.println(x+"-"+y+"-"+counter);
if (counter < neighborhoodMinCount) {
image.setRGB(x, y, whitePoint);
}
}
}
}
return this;
}
/**
* 如果点周围的黑点数达到补偿值就把这个点变为黑色
*
* @param addFlag 补偿阀值,通过观察处理过的图像确定,一般为2即可
* @return
*/
public ImageTool modifyBlank(int addFlag) {
int val, counter = 0, topLeftXIndex, topLeftYIndex, blackPoint = getBlackPoint();
Color point;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
//初始化邻居数为0
counter = 0;
topLeftXIndex = x - 1;
topLeftYIndex = y - 1;
point = new Color(image.getRGB(x, y));
//这里假定图像已经被黑白化,取Red值认为不是0就是255
val = point.getRed();
//只有白点才进行补偿
if (val == 255) {
for (int x1 = topLeftXIndex; x1 <= topLeftXIndex + 2; x1++) {
for (int y1 = topLeftYIndex; y1 <= topLeftYIndex + 2; y1++) {
//判断这个点是否存在
if (x1 < width && x1 >= 0 && y1 < height && y1 >= 0) {
//判断这个点是否是传入点的外围点
if (x1 == topLeftXIndex || x1 == topLeftXIndex + 2
|| y1 == topLeftYIndex || y1 == topLeftYIndex + 2) {
//这里假定图像已经被黑白化,取Red值认为不是0就是255
val = new Color(image.getRGB(x1, y1)).getRed();
// System.out.println(val + "--" + (centerVal));
//如果这个邻居是黑色,就把中心点的补偿数目加一
if (val == 0) {
counter++;
}
}
}
}
}
//如果这个点周围的黑点数达到补偿值就把这个点变为黑色
if (counter >= addFlag) {
image.setRGB(x, y, blackPoint);
}
}
}
}
return this;
}
public BufferedImage getBufferedImage(String filename) {
File file = new File(filename);
try {
return ImageIO.read(file);
} catch (IOException ex) {
Logger.getLogger(ImageTool.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
private boolean isBlackBlock(int startX, int startY, int blockWidth, int blockHeight) {
int counter = 0;//统计黑色像素点的个数
int total = 0;//统计有效像素点的个数
int val;
for (int x1 = startX; x1 <= startX + blockWidth - 1; x1++) {
for (int y1 = startY; y1 <= startY + blockHeight - 1; y1++) {
//判断这个点是否存在
if (x1 < width && x1 >= 0 && y1 < height && y1 >= 0) {
total++;//有效像素点的个数
//这里假定图像已经被黑白化,取Red值认为不是0就是255
val = new Color(image.getRGB(x1, y1)).getRed();
//如果这个点是黑色,就把黑色像素点的数目加一
if (val == 0) {
counter++;
}
}
}
}
// System.out.println(startX + "--" + startY + "" + (counter == total&&total!=0));
return counter == total && total != 0;
}
private int getWhitePoint() {
return (new Color(255, 255, 255).getRGB() & 0xffffffff);
}
private int getBlackPoint() {
return (new Color(0, 0, 0).getRGB() & 0xffffffff);
}
private int getAvgValue() {
Color point;
int total = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
point = new Color(image.getRGB(j, i));
total += (point.getRed() + point.getGreen() + point.getBlue()) / 3;
}
}
return total / (width * height);
}
public void saveToFile(String filePath) {
try {
String ext = filePath.substring(filePath.lastIndexOf(".") + 1);
File newFile = new File(filePath);
ImageIO.write(image, ext, newFile);
} catch (IOException ex) {
Logger.getLogger(ImageTool.class.getName()).log(Level.SEVERE, null, ex);
}
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
width = image.getWidth();
height = image.getHeight();
}
}
java 验证码图片处理类,为验证码识别做准备的更多相关文章
- c# 验证码图片生成类
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D ...
- ThinkPHP---TP功能类之验证码
[一]验证码 验证码全称:captcha(全自动识别机器与人类的图灵测试),简单理解就是区分当前操作是人执行的还是机器执行的 常见验证码分3种:页面上图片形式.短信验证码(邮箱验证可以归类到短信验证码 ...
- Java中SSM+Shiro系统登录验证码的实现方法
1.验证码生成类: import java.util.Random; import java.awt.image.BufferedImage; import java.awt.Graphics; im ...
- .Net中验证码图片生成
开发网站或平台系统,登录页面是必不可少的功能,但是现在很多人可以使用工具暴力破解网站密码,为了防止这类非法操作,需要在登录页面添加验证,验证码就是最常用的一种验证方式. 我结合了自己的经验和网上的验证 ...
- Winform中产生验证码图片
1.创建ValidCode类: public class ValidCode { #region Private Fields private const double PI = 3.14159265 ...
- 验证码在后台的编写,并实现点击验证码图片时时发生更新 C# 项目发布到IIS后不能用log4net写日志
验证码在后台的编写,并实现点击验证码图片时时发生更新 验证码在软件中的地位越来越重要,有效防止这种问题对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试:下面就是实现验证码的基本步骤: ...
- asp.net验证码图片生成示例
验证码,一个很常见的东西.不管你是使用者还是开发者,这个东西80%的人都见到过,但是之前有人给我说过这么一句话“内行看门道,外行看热闹!”,仔细琢磨一下还真的是那么一回事.对于怎么实现验证码,闲话不多 ...
- 验证码图片生成工具类——Captcha.java
验证码图片生成工具,使用JAVA生成的图片验证码,调用getRandcode方法获取图片验证码,以流的方式传输到前端页面. 源码如下:(点击下载 Captcha.java) import java. ...
- java生成图片验证码(转)--封装生成图片验证码的工具类
博客部分内容转载自 LonlySnow的博客:后台java 实现验证码生成 1.controller方法 @RequestMapping(value = "/verifycode/img&q ...
随机推荐
- 分享一些前端chm文档
分享地址:http://yun.baidu.com/share/link?shareid=39230983&uk=1008683945 对于网络不好的人来说,离线文档更加方便.打开速度更快. ...
- xshell 上传 下载文件
借助XShell,使用linux命令sz可以很方便的将服务器上的文件下载到本地,使用rz命令则是把本地文件上传到服务器. sz用法: 下载一个文件 sz filename 下载多个文件 sz file ...
- Linux_系统信息
公司里一些仿真软件得进Linux系统,好奇公司用的什么Linux版本,于是搜罗了几个命令如下: 1 uname - Print system info -a, print all info -s, ...
- Python的数据处理学习(二)
本文参考Paul Barry所著的<Head First Python>一书,参考代码均可由http://python.itcarlow.ie/站点下载.本文若有任何谬误希望不吝赐教~ 二 ...
- gradle gradlew 的使用
jcenter() 仓库比 mavenCentral() 仓库快,因此最好将jcenter 放前面,这样下载速度最快. 使用本地软件仓库:repositories { flatDir { dirs ' ...
- EntityFramwork6连接MySql错误
EntityFramwork6连接MySql错误 使用EF6连接MySql产生Exception: ProHub.ssdl(2,2) : 错误 0152: MySql.Data.MySqlClient ...
- Dagger2 scope
1. 一个没有scope的component是不能依赖于另外一个有scope的component 2.@Singleton不是真正意义的单例,比如下面 @Singleton @Component cl ...
- JavaIO(06)文件复制
文件复制一般是采用两种方式进行操作: 1:将源文件中的内容全部读取到内存中,并一次性的写入到目标文件中:(不常用这种方式) 2:不将源文件中的内容全部读取进来,而是采用边读边写的方式: 实例01: ...
- python windows错误码
在用python删除文件的时候,一直报这个错误,查了 error5的错误是 拒绝访问 在用python删除文件的时候,一直报这个错误,查了 error5的错误是 拒绝访问.那么是删除权限不够?用管理员 ...
- Python基础 字符串的魔法
capitalize(self) 返回值:将字符串的第一个首字母变成大写,其他字母变小写 s = 'hello World' ss = s.capitalize() print(ss) Hello w ...