[Java] Append string with adaptive font size to image

Ref: https://blog.csdn.net/zengrenyuan/article/details/80281738

public static ByteArrayOutputStream encodeWithWaterMark(String content) {
    if (FRONT_IMAGE == null) {
        return encode(content);
    }

    ByteArrayOutputStream os = null;

    try {
        BitMatrix matrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT);
        BufferedImage backImage = QRCodeUtils.toBufferedImage(matrix);

        int fontSize = 20;
        String stringContent = "邀請QRCode (一般)";

        Font font = new Font("Noto Sans TC", Font.PLAIN, fontSize);
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        int width = getWordWidth(font, stringContent);

        while (width > WIDTH) {  //if string width > image width ➔ use smaller font
            fontSize = fontSize - 1;
            font = new Font("Noto Sans TC", Font.PLAIN, fontSize);
            metrics = FontDesignMetrics.getMetrics(font);
            width = getWordWidth(font, stringContent);
        }

        Graphics2D g = backImage.createGraphics();

        g.setFont(font);
        g.setColor(Color.BLACK);
        //text-align:center & bottom
        g.drawString(stringContent, (WIDTH - width) / 2, HEIGHT - metrics.getAscent());              
        g.dispose();

        os = new ByteArrayOutputStream();
        if (!ImageIO.write(backImage, IMAGE_FORMAT, os)) {
            throw new IOException("Could not write an image of format png");
        }

    } catch (Exception e) {
        LOG.error(Constants.EXCEPTION_PREFIX, e);
    }

    return os;
}

private static BufferedImage toBufferedImage(BitMatrix matrix) {
    int width = matrix.getWidth();
    int height = matrix.getHeight();
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            image.setRGB(x, y, matrix.get(x, y)
                               ? BLACK
                               : WHITE);
        }
    }
    return image;
}

public static int getWordWidth(Font font, String content) {
    FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
    int width = 0;
    for (int i = 0; i < content.length(); i++) {
        width += metrics.charWidth(content.charAt(i));
    }
    return width;
}
This entry was posted in Java. Bookmark the permalink.