src/org/nutz/img/Images.java
public static BufferedImage createCaptcha(String content,
                                              int width,
                                              int height,
                                              String fontColor,
                                              String bgColor,
                                              String fontName) {
        // 处理下参数
        if (Strings.isBlank(content)) {
            return null;
        }
        boolean isChinese = Strings.isChineseCharacter(content.charAt(0));
        if (width <= 0) {
            // 中文字体的话，间距需要多一些
            width = content.length() * (isChinese ? 25 : 20) + 20;
        }
        if (height <= 0) {
            height = 30;
        }
        Color userColor = Strings.isBlank(fontColor) ? null : Colors.as(fontColor);
        Color colorBg = Strings.isBlank(bgColor) ? Colors.randomColor() : Colors.as(bgColor);

        // 生成背景
        BufferedImage im = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D gc = im.createGraphics();
        gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        gc.setBackground(colorBg);
        gc.clearRect(0, 0, width, height);

        // 加入干扰线
        for (int i = 0; i < 7; i++) {
            gc.setColor(userColor == null ? Colors.randomColor(5, 250) : userColor);
            int x = R.random(0, width);
            int y = R.random(0, height);
            int x1 = R.random(0, width);
            int y1 = R.random(0, height);
            gc.drawLine(x, y, x1, y1);
        }

        // 写入文字
        int rx = 10;
        int ry = isChinese ? height - 8 : height - 10;
        for (int i = 0; i < content.length(); i++) {
            int fontStyle = R.random(0, 3);
            int fontSize = R.random(height - 10, height - 5);
            Font textFont = Strings.isBlank(fontName) ? Fonts.random(fontStyle, fontSize)
                                                      : Fonts.get(fontName, fontStyle, fontSize);
            gc.setColor(userColor == null ? Colors.randomColor(10, 250) : userColor);
            gc.setFont(textFont);
            // 设置字体旋转角度
            int degree = R.random(0, 64) % 30;
            // 正向角度
            gc.rotate(degree * Math.PI / 180, rx, ry);
            gc.drawString(content.charAt(i) + "", rx, ry);
            // 反向角度
            gc.rotate(-degree * Math.PI / 180, rx, ry);
            rx += (isChinese ? 5 : 0) + width / (content.length() + 2);
        }

        // 图像扭曲
        im = twist(im, 1, bgColor);
        return im;
    }
public static BufferedImage createCaptcha(String content,
                                              int width,
                                              int height,
                                              String fontColor,
                                              String bgColor,
                                              String fontName) {
        // 处理下参数
        if (Strings.isBlank(content)) {
            return null;
        }
        boolean isChinese = Strings.isChineseCharacter(content.charAt(0));
        if (width <= 0) {
            // 中文字体的话，间距需要多一些
            width = content.length() * (isChinese ? 25 : 20) + 20;
        }
        if (height <= 0) {
            height = 30;
        }
        Color userColor = Strings.isBlank(fontColor) ? null : Colors.as(fontColor);
        Color colorBg = Strings.isBlank(bgColor) ? Colors.randomColor() : Colors.as(bgColor);

        // 生成背景
        BufferedImage im = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D gc = im.createGraphics();
        gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        gc.setBackground(colorBg);
        gc.clearRect(0, 0, width, height);

        // 加入干扰线
        for (int i = 0; i < 7; i++) {
            gc.setColor(userColor == null ? Colors.randomColor(5, 250) : userColor);
            int x = R.random(0, width);
            int y = R.random(0, height);
            int x1 = R.random(0, width);
            int y1 = R.random(0, height);
            gc.drawLine(x, y, x1, y1);
        }

        // 写入文字
        int rx = 10;
        int ry = isChinese ? height - 8 : height - 10;
        for (int i = 0; i < content.length(); i++) {
            int fontStyle = R.random(0, 3);
            int fontSize = R.random(height - 10, height - 5);
            Font textFont = Strings.isBlank(fontName) ? Fonts.random(fontStyle, fontSize)
                                                      : Fonts.get(fontName, fontStyle, fontSize);
            gc.setColor(userColor == null ? Colors.randomColor(10, 250) : userColor);
            gc.setFont(textFont);
            // 设置字体旋转角度
            int degree = R.random(0, 64) % 30;
            // 正向角度
            gc.rotate(degree * Math.PI / 180, rx, ry);
            gc.drawString(content.charAt(i) + "", rx, ry);
            // 反向角度
            gc.rotate(-degree * Math.PI / 180, rx, ry);
            rx += (isChinese ? 5 : 0) + width / (content.length() + 2);
        }

        // 图像扭曲
        im = twist(im, 1, bgColor);
        return im;
    }
根据指定文字内容，生成验证码

@param content
文字内容
@param width
图片宽度
@param height
图片高度
@param fontColor
文字颜色 默认黑色
@param bgColor
背景颜色 默认白色
@return 图像