实现图片验证码(拖拉验证),包括前后端源码。
限定尝试拖拽4次,尝试4次不成功,将原图片将失效,需重新生成新图片(点击刷新按钮)。
项目只需配置Redis地址和MySql数据库就可以,MySql不需要实际的表数据。
运行项目后,直接访问地址:http://localhost:8888/index.html 。
滑动图片带描边,适配后,将去掉描边。
源码见: https://github.com/37412449/picture-verification-code
主要功能文件为:src\main\java\com\verification\code\util\VerifyImageUtil.java
如实现抠图、描边等主要功能函数为:
private static byte[] dealOriPictureByTemplate(BufferedImage oriImage, BufferedImage templateImage, int x,
int y) throws Exception {
// 源文件备份图像矩阵 支持alpha通道的rgb图像
BufferedImage oriCopyImage = new BufferedImage(oriImage.getWidth(), oriImage.getHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
// 源文件图像矩阵
int[][] oriImageData = getData(oriImage);
// 模板图像矩阵
int[][] templateImageData = getData(templateImage);
//copy 源图做不透明处理
for (int i = 0; i < oriImageData.length; i++) {
for (int j = 0; j < oriImageData[0].length; j++) {
int rgb = oriImage.getRGB(i, j);
int r = (0xff & rgb);
int g = (0xff & (rgb >> 8));
int b = (0xff & (rgb >> 16));
//无透明处理
rgb = r + (g << 8) + (b << 16) + (255 << 24);
oriCopyImage.setRGB(i, j, rgb);
}
}
for (int i = 0; i < templateImageData.length; i++) {
for (int j = 0; j < templateImageData[0].length - 5; j++) {
int rgb = templateImage.getRGB(i, j);
//对源文件备份图像(x+i,y+j)坐标点进行透明处理
if (rgb <= 0) {
/*
// 注销被扣掉图片位置透明处理,改为直接设置为制定颜色
int rgb_ori = oriCopyImage.getRGB(x + i, y + j);
int r = (0xff & rgb_ori);
int g = (0xff & (rgb_ori >> 8));
int b = (0xff & (rgb_ori >> 16));
rgb_ori = r + (g << 8) + (b << 16) + (150 << 24);
oriCopyImage.setRGB(x + i, y + j, rgb_ori);
*/
oriCopyImage.setRGB(x + i, y + j, MAT_BG_COLOR.getRGB());
}
}
}private static BufferedImage dealCutPictureByTemplate(BufferedImage oriImage, BufferedImage templateImage,
BufferedImage targetImage) {
// 源文件图像矩阵
int[][] oriImageData = getData(oriImage);
// 模板图像矩阵
int[][] templateImageData = getData(templateImage);
// 描边
Color lineColor = new Color(250, 149, 47);
boolean leftFlag, rightFlag, upFlag, downFlag;
_linePoint.clear();
// 模板图像宽度
for (int i = 0; i < templateImageData.length; i++) {
// 模板图片高度
for (int j = 0; j < templateImageData[0].length; j++) {
leftFlag = rightFlag = upFlag = downFlag = false;
// 如果模板图像当前像素点不是白色 copy源文件信息到目标图片中
int rgb = templateImageData[i][j];
if (rgb > 0) {
continue;
}
// 如果是最边上有点,直接描边
if (i == 0 || j == 0 || i == templateImageData.length - 1 || j == templateImageData[0].length - 1) {
targetImage.setRGB(i, j, lineColor.getRGB());
continue;
}
// 上判断[i][j+1]
if (j < templateImageData[i].length - 1) {
if (templateImageData[i][j + 1] < 0) {
upFlag = true;
}
}
// 下判断 [i][j-1]
if (templateImageData[i][j - 1] < 0) {
downFlag = true;
}
// 左判断[i-1][j]
if (templateImageData[i - 1][j] < 0) {
leftFlag = true;
}
// 右判断[i+1][j]
if (i < templateImageData.length - 1) {
if (templateImageData[i + 1][j] < 0) {
rightFlag = true;
}
}
if (!(leftFlag && rightFlag && upFlag && downFlag)) {
targetImage.setRGB(i, j, lineColor.getRGB());
_linePoint.add(new int[]{i, j, oriImageData[i][j]});
} else {
targetImage.setRGB(i, j, oriImageData[i][j]);
}
}
}
return targetImage;
}具体效果见下图:



版权声明:本文为lianganton原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。