java生成验证码图片中仅有线条_java实现图片滑动验证码优化

因对系统安全性的要求,需要实现后台生成 图片滑动验证码的需求。

最开始接到这个需求,脑子里一片雾水,流程均清楚,可切图对我这个普通的小码农来说太难了,于是便上网查询资料,结果惊喜的发现了一位博主的文章(链接地址:https://blog.csdn.net/qq_36892341/article/details/86644580),具体步骤该文章中均有列出,就不缀述了~

在充分参考该博主的文章后,发现实际结果不是很理想:

882738f10088676596f3f3d5baaf2298.png
最初版

如上图,切出来的小图几乎和大图背景融为一体,扣掉的那块儿因为要保证在每张图上都很明显,就改了个固定色,但比起之前纯前端画的图,简直是天差地别

55d2808b4a5180194a1f9699e40d6e93.png
纯前端切图

于是在原来代码的基础上,参考前端切图的样式,计划给抠下来的小图加上白色边框,并将大图上被抠掉部分的底色换成白色!于是经过一波对博主代码的分析及精密计算(实际上就运用了个勾股定理,哈哈),最终做出了下图的效果:

9f5b9e313104b76b21db13e5bdac466a.png
最终优化图

下面就要贴出干货了——我修改后的代码:

/**
     *
     * @Createdate: 2019年1月24日上午10:52:42
     * @Title: getBlockData
     * @Description: 生成小图轮廓
     * @author mzl
     * @return int[][]
     * @throws
     */
    private int[][] getBlockData() {

        int[][] data = new int[targetLength][targetWidth];
        double x2 = targetLength-circleR;

        //随机生成圆的位置
//        double h1 = circleR + Math.random() * (targetWidth-3*circleR-r1);
        double h1 = 20.678101695669376;
        double po = circleR*circleR;

        double xbegin = targetLength-circleR-r1;
        double ybegin = targetWidth-circleR-r1;

        for (int i = 0; i < targetLength; i++) {
            for (int j = 0; j < targetWidth; j++) {
                double d3 = Math.pow(i - x2,2) + Math.pow(j - h1,2);
                double d2 = Math.pow(j-2,2) + Math.pow(i - h1,2);
                if ((j < ybegin && d2 < po)||(i > xbegin && d3 > po)) {
                    data[i][j] = 0;
                }  else {
                    data[i][j] = 1;
//                    || i == targetLength-2 || i == targetLength-1
                    // 边框部分置为2(取两个宽度)
                    if (i == 0 || i==1 || i == targetLength-1 || j == 0 || j == 1 || j == targetWidth-2 || j == targetWidth-1){
                        data[i][j] = 2;
                    }
                    if ((j <= ybegin && Math.abs(Math.sqrt(d2)-circleR) < 2)||(i >= xbegin-1 && Math.abs(Math.sqrt(d3)-circleR) < 2)) {
                        data[i][j] = 2;
                    }
                    if ((i == xbegin || i == xbegin-1) && (j <= Math.sqrt(po-Math.pow(r1,2)) || j >= ybegin)){
                        data[i][j] = 2;
                    }

                }

            }
        }
        return data;
    }

    /**
     *
     * @Createdate: 2019年1月24日上午10:51:30
     * @Title: cutByTemplate
     * @Description: 生成小图片、给大图片添加阴影
     * @author mzl
     * @param oriImage
     * @param targetImage
     * @param templateImage
     * @param x
     * @param y void
     * @throws
     */
    private void cutByTemplate(BufferedImage oriImage, BufferedImage targetImage, int[][] templateImage, int x, int y){
        for (int i = 0; i < targetLength; i++) {
            for (int j = 0; j < targetWidth; j++) {
                int rgb = templateImage[i][j];
                // 原图中对应位置变色处理
                int count = 0;
                do {
                    try {
                        int rgb_ori = oriImage.getRGB(x + i, y + j);

                        if (rgb == 1) {
                            //抠图上复制对应颜色值
                            targetImage.setRGB(i, j, rgb_ori);
                            //原图对应位置颜色变化
//                            oriImage.setRGB(x + i, y + j, rgb_ori & 0x363636 );
                            oriImage.setRGB(x + i, y + j, 0x88F5F5F5);
                        }else if (rgb == 2){
//                            targetImage.setRGB(i, j, rgb_ori & 0xff000000);
//                            oriImage.setRGB(x + i, y + j, rgb_ori & 0xff000000);
                            // 边框设为白色
                            targetImage.setRGB(i, j, 0xffffffff);
                            oriImage.setRGB(x + i, y + j, 0xffffffff);
                        }else if (rgb == 0){
                            //这里把背景设为透明
                            targetImage.setRGB(i, j, rgb_ori & 0x00ffffff);
                        }
                    } catch (Exception e) {
                        count++;
                    }
                } while (count > 0 && count < 5);
            }
        }
    }

虽然这样做出来的图还是很丑,但起码看着效果好了很多~

目前很遗憾的一点就是自己实在能力有限,不会如前端切图那样,给大图被抠掉部分加上透明罩层,如有大神莅临,请多多指教~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值