Easy-Captche的绘画方法

发布时间 2023-04-25 17:47:04作者: 之士咖啡

EasyCaptche 功能有 5个验证码类型,分别为

  • png类型
  • jpg类型
  • 中文类型
  • 中文jpg类型
  • 算数类型
    这5个对象中都会有graphicsImage() 方法,其功能是将内容画出来。

效果展示:
image

绘画方法:在画板上一点一点画

// 以下方法,为 SpecCaptcha 中的 out 方法体
private boolean graphicsImage(char[] strs, OutputStream out) {
        try {
            // 画板
            // 1. 使用缓存流用于 存储图片内容
            BufferedImage bi = new BufferedImage(this.width, this.height, 1);
            // 2. 使用 Graphics2D 进行绘图
            Graphics2D g2d = (Graphics2D)bi.getGraphics();
            // 背景颜色
            g2d.setColor(Color.WHITE);
            // 背景填范围
            g2d.fillRect(0, 0, this.width, this.height);
            // 模糊边缘程度
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            // 画一背景
            this.drawOval(2, g2d);
            // 设置画笔属性
            g2d.setStroke(new BasicStroke(2.0F, 0, 2));
            // 画线
            this.drawBesselLine(1, g2d);
            // 设置字体
            g2d.setFont(this.getFont());
            // 字体度量
            FontMetrics fontMetrics = g2d.getFontMetrics();
            // 单个字体所占宽度
            int fW = this.width / strs.length;
            // 单个字体空余宽度/2
            int fSp = (fW - (int)fontMetrics.getStringBounds("W", g2d).getWidth()) / 2;

            for(int i = 0; i < strs.length; ++i) {
                // 设置字体颜色
                g2d.setColor(this.color());
                // 字体距离顶部的距离
                int fY = this.height - (this.height - (int)fontMetrics.getStringBounds(String.valueOf(strs[i]), g2d).getHeight() >> 1);
                // 画字
                g2d.drawString(String.valueOf(strs[i]), i * fW + fSp + 3, fY - 3);
            }
            // 3. 停止绘画
            g2d.dispose();
            // 4. 生成绘画图片
            ImageIO.write(bi, "png", out);
            out.flush();
            boolean var20 = true;
            return var20;
        } catch (IOException var18) {
            var18.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException var17) {
                var17.printStackTrace();
            }
        }
        return false;
    }
ChineseGifCaptcha 中的 out 方法体
private BufferedImage graphicsImage(Color[] fontColor, char[] strs, int flag, int[][] besselXY) {
		// 1. 使用缓存流用于 存储图片内容
        BufferedImage image = new BufferedImage(this.width, this.height, 1);
		// 2. 使用 Graphics2D 进行绘图
        Graphics2D g2d = (Graphics2D)image.getGraphics();
		// 背景颜色
        g2d.setColor(Color.WHITE);
		// 背景填充访问
        g2d.fillRect(0, 0, this.width, this.height);
		// 模糊边缘程度
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		// 设置透明度( 0.1F * (float)num(10))
        g2d.setComposite(AlphaComposite.getInstance(3, 0.1F * (float)num(10)));
		// 画两个圆
        this.drawOval(2, g2d);
		// 设置透明度( 0.7F)
        g2d.setComposite(AlphaComposite.getInstance(3, 0.7F));
		// 画笔属性
        g2d.setStroke(new BasicStroke(1.2F, 0, 2));
		// 画笔颜色
        g2d.setColor(fontColor[0]);
		// 三段曲线段
        CubicCurve2D shape = new Double((double)besselXY[0][0], (double)besselXY[0][1], (double)besselXY[1][0], (double)besselXY[1][1], (double)besselXY[2][0], (double)besselXY[2][1], (double)besselXY[3][0], (double)besselXY[3][1]);
		// 花曲线
        g2d.draw(shape);
		// 字体
        g2d.setFont(this.getFont());
		// 字体度量
        FontMetrics fontMetrics = g2d.getFontMetrics();
		// 单个字体所占宽度
        int fW = this.width / strs.length;
		// 单个字体空余宽度/2
        int fSp = (fW - (int)fontMetrics.getStringBounds("W", g2d).getWidth()) / 2;

        for(int i = 0; i < strs.length; ++i) {
			// 字体透明度
            AlphaComposite ac3 = AlphaComposite.getInstance(3, this.getAlpha(flag, i));
			
            g2d.setComposite(ac3);
			// 字体颜色
            g2d.setColor(fontColor[i]);
            // 字体距离顶部的距离
            int fY = this.height - (this.height - (int)fontMetrics.getStringBounds(String.valueOf(strs[i]), g2d).getHeight() >> 1);
			// 画字
            g2d.drawString(String.valueOf(strs[i]), i * fW + fSp - 3, fY - 3);
        }
		// 停止回话
        g2d.dispose();
        return image;
    }

通过以上代码,可以简单 captcha 图片的实现方式。对此,我们可以模仿写下 “给图片添加水印”,毕竟都是绘画功能。

水印的原理:在原图片上画上水印。使用的是 Graphics2D。