实现图片抠图,拖拽验证功能

发布于:2022-07-26 ⋅ 阅读:(331) ⋅ 点赞:(0)

实现图片验证码(拖拉验证),包括前后端源码。

限定尝试拖拽4次,尝试4次不成功,将原图片将失效,需重新生成新图片(点击刷新按钮)。

项目只需配置Redis地址就可以。

运行项目后,直接访问地址: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;
}

具体效果见下图:

本文含有隐藏内容,请 开通VIP 后查看