1, 效果

图片都是280x210

2, 切图工具

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;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); //读取原始图片Iterator<ImageReader>it=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();}}public void cutByTemplate2(BufferedImage oriImage,BufferedImage newSrc,BufferedImage newSrc2,int x,int y,int width,int height, int c_a, int c2_b){//固定圆半径为5int c_r=10;double rr=Math.pow(c_r, 2);//r平方//圆心的位置 cb//System.out.println(c_a);int c_b=y;//第二个圆(排除圆内的点) c2_aint c2_a=x;//System.out.println(oriImage.getWidth()+"   "+oriImage.getHeight());for(int i=0;i<oriImage.getWidth();i++){for(int j=0;j<oriImage.getHeight();j++){//data[i][j]=oriImage.getRGB(i,j);//(x-a)²+(y-b)²=r²中,有三个参数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<(x+width) &&j>=y&&j<(y+height) && f2>=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);newSrc.setRGB(i + 1, j + 1, 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 BufferedImage createDropShadow(BufferedImage image,int size, float opacity) {int width = image.getWidth() + size * 2;int height = image.getHeight() + size * 2;BufferedImage mask = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB);Graphics2D g2 = mask.createGraphics();g2.drawImage(image, size, size, null);g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN,opacity));g2.setColor(Color.BLACK);g2.fillRect(0, 0, width, height);g2.dispose();BufferedImage shadow = createBlurOp(size).filter(mask, null);g2 = shadow.createGraphics();g2.dispose();return shadow;}private static ConvolveOp createBlurOp(int size) {float[] data = new float[size * size];float value = 1f / (float) (size * size);for (int i = 0; i < data.length; i++) {data[i] = value;}return new ConvolveOp(new Kernel(size, size, data),ConvolveOp.EDGE_NO_OP, null);}
}

3, 生成背景图

x就是验证码, x 轴的偏移量, 验证就是需要这个

@GetMapping("/xcode")public Result getXCode1(HttpServletResponse resp, HttpServletRequest request) throws IOException {ImageUtil tt = new ImageUtil();// 随机选择背景图int num = new Random().nextInt(10) + 1;InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("xcode/" + num + ".jpg");BufferedImage src= ImageIO.read(resourceAsStream);//移动图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=48;int blockHeight=48;// 用于生成 移动图XCodeTdo code = new XCodeTdo();code.setNum(num);Random rand1=new Random();int x=rand1.nextInt(src.getWidth()-blockWidth-20)+20;//10,width-200if (x > 210 - 58) {x = 210 - 58;}Random rand2=new Random();int y=rand2.nextInt(src.getHeight()-blockHeight-20)+20;//code.setX(x);code.setY(y);int ca = new Random().nextInt(blockWidth-2*20)+(x+20);int cb = new Random().nextInt(blockHeight-2*20)+(y+20);code.setCa(ca);code.setCb(cb);tt.cutByTemplate2(src,newSrc,newSrc2,x,y,blockWidth,blockHeight, ca, cb);//图片大小是固定,位置是随机request.getSession().setAttribute("X_CODE", JSON.toJSONString(code));//生成对比图ImageIO.write(newSrc2, "png", resp.getOutputStream());return null;}

4, 生成区块图

@GetMapping("/xcodem")public Result getXCode2(HttpServletResponse resp, HttpServletRequest request) throws IOException {ImageUtil tt = new ImageUtil();Object o = request.getSession().getAttribute("X_CODE");if (o == null) {return new Result();}XCodeTdo codeTdo = JSON.parseObject(String.valueOf(o), XCodeTdo.class);int num = codeTdo.getNum();InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("xcode/" + num + ".jpg");BufferedImage src= ImageIO.read(resourceAsStream);//移动图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 x= codeTdo.getX();int y= codeTdo.getY();tt.cutByTemplate2(src,newSrc,newSrc2,x,y,48,48, codeTdo.getCa(), codeTdo.getCb());//图片大小是固定,位置是随机newSrc = newSrc.getSubimage(x - 1, 0, 58, 210);//ImageUtil.createDropShadow(newSrc, 3, 0.08f);//生成对比图ImageIO.write(newSrc, "png", resp.getOutputStream());return null;}

5, 阴影图

@GetMapping("/xcodey")public void getXCode3(HttpServletResponse resp, HttpServletRequest request) throws IOException {ImageUtil tt = new ImageUtil();Object o = request.getSession().getAttribute("X_CODE");if (o == null) {return;}XCodeTdo codeTdo = JSON.parseObject(String.valueOf(o), XCodeTdo.class);int num = codeTdo.getNum();InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("xcode/" + num + ".jpg");BufferedImage src= ImageIO.read(resourceAsStream);//移动图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 x= codeTdo.getX();int y= codeTdo.getY();tt.cutByTemplate2(src,newSrc,newSrc2,x,y,48,48, codeTdo.getCa(), codeTdo.getCb());//图片大小是固定,位置是随机newSrc = newSrc.getSubimage(x - 1, 0, 48, 210);newSrc = ImageUtil.createDropShadow(newSrc, 4, 0.6f);//生成对比图ImageIO.write(newSrc, "png", resp.getOutputStream());}
public class XCodeTdo {private int num;private int x;private int y;private int ca;private int cb;public int getNum() {return num;}public void setNum(int num) {this.num = num;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public int getCa() {return ca;}public void setCa(int ca) {this.ca = ca;}public int getCb() {return cb;}public void setCb(int cb) {this.cb = cb;}
}

4, 怎么验证?

前端需要传 x 轴的偏移量, 与第一次生成的背景图保存在session 中的 X_CODE, 中的x进行比较值

@RequestMapping(value = "/login", method = RequestMethod.POST)@ResponseBodypublic Object loginVali(HttpServletRequest request) {String username = super.getPara("username").trim();String password = super.getPara("password").trim();String xcode= super.getPara("xcode");int token = Integer.parseInt(xcode);Object obj = request.getSession().getAttribute("X_CODE");XCodeTdo codeTdo = JSON.parseObject(String.valueOf(obj), XCodeTdo.class);// 这里 / 2.1 是因为前端的滑动器值是100int x = (int) (codeTdo.getX() / 2.1);// 预留了正负6 * 2.1 = 13的像素的偏差if (token > x + 3 || token < x - 3) {// 删除验证记录request.getSession().removeAttribute("X_CODE");return new SuccessTip(400,"验证码错误!",null);}return new SuccessTip(200,"登录成功!",null);}

Java 生成滑动图片验证码, 阴影, 切块相关推荐

  1. Java生成随机图片验证码工具类

    一.第一种生成随机图片验证码 public class VerifyCodeUtil {//生成随机数据的数据源 public static final String VERIFY_CODES = & ...

  2. 实现Java生成随机图片验证码

    前言 这篇文章主要介绍了如何通过Java如何生成验证码并验证.验证码的作用我想必大家都知道,话不多说开始实施! 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 1.项 ...

  3. Java中使用图片验证码 --菜鸟小回

    Java中使用图片验证码 一.第一种方式 工具类 @WebServlet("/BufferImage") public class BufferImage extends Http ...

  4. java生成表格图片(请假条为例)

    java生成表格图片(请假条) package table;import java.awt.Color; import java.awt.Font; import java.awt.Graphics; ...

  5. php 生成gif验证码,PHP生成Gif图片验证码

    验证码在好多地方都要用到,这里提供一个新开发的安全验证码类,支持生成Gif图片验证码(带噪点,干扰线,网格,随机色背景,随机自定义字体,倾斜,Gif动画). 先看效果图 字体及字体文件的路径需要在类中 ...

  6. 致敬Gif之父,使用Java生成Gif图片

    点击关注强哥,查看更多精彩文章呀 哈喽,大家好,我是强哥. 据美国媒体报道,美国计算机科学家.GIF图像格式发明人斯蒂芬•威尔海特(Stephen Wilhite)于当地时间3月14日因新冠肺炎去世, ...

  7. java生成小图片_JAVA生成缩略小图片类

    JAVA生成缩略小图片类 java.awt.image.BufferedImage是缓冲图片类主要将生成的图片对象缓冲起来:javax.imageio.ImageIO是图片IO控制类,可以将缓冲图片对 ...

  8. java生成条码图片、打印二维码、图片合并、图片加文字

    通过java生成二维码图片,可以添加文字内容,非常方便实现打印. import java.awt.Color; import java.awt.Font; import java.awt.FontMe ...

  9. WordPress登录注册评论滑动图片验证码插件腾讯云验证码(CAPTCHA)

    为了网站安全我们一般会在登录页.注册页.评论页添加验证码功能,传统的验证码都是输入字母数字或加减法等,现在比较流行图片滑动验证码.最为关键的是腾讯云提供有图形验证(图片滑动验证码)服务器(一年内提供几 ...

最新文章

  1. 安卓ttf格式的字体包_苹果官网御用字体
  2. python字符串split_「干货」Python字符串中的split方法
  3. 怎么随时获取Spring的上下文ApplicaitonContext,和Spring管理的Bean
  4. Codeforces Round #183 (Div. 2)
  5. 【渝粤教育】国家开放大学2018年秋季 0149-21T现代汉语 参考试题
  6. 理解C++中拷贝构造函数
  7. mulitpartfile怎么接收不到值_手机有时接收不到微信消息通知,怎么办?超全解决方案...
  8. MapReduce寻找共同好友
  9. JavaScript 统计中英混合字符串的长度
  10. yocto rootfs 支持pam
  11. day20 Python 高阶函数,函数,嵌套,闭包 装饰器
  12. HDU 6030(矩阵快速幂+规律)
  13. [编程] C语言变量和数据类型总结练习题
  14. python里面的冒号_python里的冒号
  15. spss进行相关性分析
  16. 道法演讲之马云从事教育
  17. 首位华人女数学家获拉马努金奖!北大数院校友,陶哲轩恽之玮曾得过此奖
  18. 排序(使用插入法对数组元素从小到大排序)
  19. 设计字体时字体性格的分类表现(二)
  20. 全自动化处理每月缺卡数据,输出缺卡人员信息

热门文章

  1. 最短路径的Dijkstra算法(邻接表)
  2. H3C 交换机S5130S软件版本升级
  3. c语言循环设计思想结构,C语言程序设计_05循环结构程序设计讲述.pptx
  4. git 代码回退_「Vue 入门系列」第三期,适合新手入门的 Git 使用教程
  5. 如何在Eclipse中添加新建包,java文件,工程工具栏按钮
  6. httpClient 超时时间设置
  7. cppcheck编译安装命令
  8. http提交json格式数据自动加\
  9. 简单android音乐播放器课程设计,android音乐播放器课程设计报告.doc
  10. 1个ieee1394端口_如何使用圆形端口进行波导激励和终止