java 拖动验证码实现_java实现拖动图片验证码

本文介绍了如何使用Java生成拖动验证码,包括从原始图片中裁剪出底图和移动图,涉及图像处理和随机位置生成。示例代码展示了如何进行图像裁剪和保存,但未涵盖前端实现。
摘要由CSDN通过智能技术生成

思路是,对原图产生两张图片,一张是底图,被抠掉一部分的图片,另外一张是移动图,被抠出的来部分

只写了后台怎么生成拖动验证码的两个图片,前端的还没写,待续。以下是后台的代码

class="java">

/*

* 根据源图片,剪切出两张图

* */

package com.chainway.dragimgvalidate;

import java.awt.Rectangle;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.util.Iterator;

import java.util.Random;

import javax.imageio.ImageIO;

import javax.imageio.ImageReadParam;

import javax.imageio.ImageReader;

import javax.imageio.stream.ImageInputStream;

public class ImageUtil {

public static void cut(int x,int y,int width,int height,String srcpath,String subpath) throws IOException {//裁剪方法

FileInputStream is=null;

ImageInputStream iis=null;

try{

is=new FileInputStream(srcpath); //读取原始图片

Iteratorit=ImageIO.getImageReadersByFormatName("jpg"); //ImageReader声称能够解码指定格式

ImageReader reader=it.next();

iis=ImageIO.createImageInputStream(is); //获取图片流

reader.setInput(iis, true); //将iis标记为true(只向前搜索)意味着包含在输入源中的图像将只按顺序读取

ImageReadParam param=reader.getDefaultReadParam(); //指定如何在输入时从 Java Image I/O框架的上下文中的流转换一幅图像或一组图像

Rectangle rect=new Rectangle(x, y, width, height); //定义空间中的一个区域

param.setSourceRegion(rect); //提供一个 BufferedImage,将其用作解码像素数据的目标。

BufferedImage bi=reader.read(0, param); //读取索引imageIndex指定的对象

ImageIO.write(bi, "jpg", new File(subpath)); //保存新图片

}finally{

if(is!= null)

is.close();

if(iis != null)

iis.close();

}

}

private void cutByTemplate2(BufferedImage oriImage,BufferedImage newSrc,BufferedImage newSrc2,int x,int y,int width,int height){

//固定圆半径为5

int c_r=20;

double rr=Math.pow(c_r, 2);//r平方

//圆心的位置

Random rand=new Random();

int c_a=rand.nextInt(width-2*c_r)+(x+c_r);//x+c_r+10;//圆心x坐标必须在(x+r,x+with-r)范围内

//System.out.println(c_a);

int c_b=y;

//第二个圆(排除圆内的点)

Random rand2=new Random();

int c2_a=x;

int c2_b=rand2.nextInt(height-2*c_r)+(y+c_r);//y+c_r+50;//圆心y坐标必须在(y+r,y+height-r)范围内

//System.out.println(oriImage.getWidth()+" "+oriImage.getHeight());

for(int i=0;i

for(int j=0;j

//data[i][j]=oriImage.getRGB(i,j);

//(x-a)2+(y-b)2=r2中,有三个参数a、b、r,即圆心坐标为(a,b),半径r。

double f=Math.pow((i-c_a), 2)+Math.pow((j-c_b), 2);

double f2=Math.pow((i-c2_a), 2)+Math.pow((j-c2_b), 2);

int rgb=oriImage.getRGB(i,j);

if(i>=x&&i=y&&j=rr){//在矩形内

//块范围内的值

in(newSrc, newSrc2, i, j, rgb);

}else if(f<=rr){

//在圆内

in(newSrc, newSrc2, i, j, rgb);

}else{

//剩余位置设置成透明

out(newSrc, newSrc2, i, j, rgb);

}

}

}

}

private void in(BufferedImage newSrc,BufferedImage newSrc2,int i,int j,int rgb){

newSrc.setRGB(i, j, rgb);

//原图设置变灰

int r = (0xff & rgb);

int g = (0xff & (rgb >> 8));

int b = (0xff & (rgb >> 16));

rgb = r + (g << 8) + (b << 16) + (100 << 24);

//rgb = r + (g << 8) + (b << 16);

newSrc2.setRGB(i, j, rgb);

}

private void out(BufferedImage newSrc,BufferedImage newSrc2,int i,int j,int rgb){

newSrc.setRGB(i, j, 0x00ffffff);

newSrc2.setRGB(i, j, rgb);

}

public static void main(String[]args)throws Exception {

ImageUtil tt=new ImageUtil();

//图片必须是png格式,因为需要做透明背景

//原图

BufferedImage src=ImageIO.read(new File("E:/temp/1.png"));

//移动图

BufferedImage newSrc=new BufferedImage(src.getWidth(), src.getHeight(),BufferedImage.TYPE_4BYTE_ABGR);//新建一个类型支持透明的BufferedImage

//对比图

BufferedImage newSrc2=new BufferedImage(src.getWidth(), src.getHeight(),BufferedImage.TYPE_4BYTE_ABGR);//新建一个类型支持透明的BufferedImage

//抠块的大小

int blockWidth=200;

int blockHeight=200;

Random rand1=new Random();

int x=rand1.nextInt(src.getWidth()-blockWidth-20)+20;//10,width-200

Random rand2=new Random();

int y=rand2.nextInt(src.getHeight()-blockHeight-20)+20;//

tt.cutByTemplate2(src,newSrc,newSrc2,x,y,blockWidth,blockHeight);//图片大小是固定,位置是随机

//生成移动图

ImageIO.write(newSrc, "png", new File("E:/temp/3.png"));

//生成对比图

ImageIO.write(newSrc2, "png", new File("E:/temp/4.png"));

}

}

效果图如下:

9dbf2d2cbafba1a902da48124e6f6667.png

edb75b81512623830edaaee512be2b20.png

大小: 822.2 KB

查看图片附件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值