Java实现文字图片

发布于:2025-07-13 ⋅ 阅读:(15) ⋅ 点赞:(0)

编写工具类

@Slf4j
public class UserIdAvatarGeneratorUtil {

    /**
     * 生成用户ID头像并返回 Base64 编码的 PNG 图片字符串
     *
     * @param userId 用户ID
     * @return Base64编码的图片字符串
     */
    public static String generateImgBase64(String userId) {
        int width = 200;
        int height = 200;

        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) bi.getGraphics();

        // 抗锯齿设置
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // 获取随机背景颜色
        Color bgColor = getRandomColor();
        g2.setBackground(bgColor);
        g2.clearRect(0, 0, width, height);

        // 根据背景颜色决定文字颜色(黑色 还是 白色,避免看不清)
        Color fontColor = isDarkColor(bgColor) ? Color.WHITE : Color.BLACK;
        g2.setPaint(fontColor);

        // 设置字体,并动态计算合适的字体大小
        Font font = new Font("微软雅黑", Font.PLAIN, 40); // 初始字体大小
        g2.setFont(font);

        FontMetrics fm = g2.getFontMetrics();
        int textWidth = fm.stringWidth(userId);

        // 如果文字太宽,缩小字体
        while (textWidth > width - 40) {
            font = new Font("微软雅黑", Font.PLAIN, font.getSize() - 1);
            g2.setFont(font);
            fm = g2.getFontMetrics();
            textWidth = fm.stringWidth(userId);
        }

        // 居中绘制文本
        int widthX = (width - textWidth) / 2;
        int heightY = (height - fm.getHeight()) / 2 + fm.getAscent();

        g2.drawString(userId.toUpperCase(), widthX, heightY);

        // 添加圆角效果(近似圆形)
        BufferedImage rounded = makeRoundedCorner(bi, 100);

        // 输出为 Base64 字符串
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(rounded, "png", byteArrayOutputStream);
            byte[] imageBytes = byteArrayOutputStream.toByteArray();
            return Base64.getEncoder().encodeToString(imageBytes);
        } catch (IOException e) {
            log.error("生成图片转换成base64错误");
            return null;
        }
    }

    /**
     * 判断背景颜色是否为“深色”,决定使用白色还是黑色字体
     */
    private static boolean isDarkColor(Color color) {
        double brightness = (color.getRed() * 299 + color.getGreen() * 587 + color.getBlue() * 114) / 1000.0;
        return brightness < 130; // 亮度小于130时认为是深色
    }

    /**
     * 随机背景颜色
     */
    private static Color getRandomColor() {
        Random rand = new Random();
        int r = rand.nextInt(256);
        int g = rand.nextInt(256);
        int b = rand.nextInt(256);
        return new Color(r, g, b);
    }

    /**
     * 图片添加圆角
     */
    public static BufferedImage makeRoundedCorner(BufferedImage image, int cornerRadius) {
        int w = image.getWidth();
        int h = image.getHeight();
        BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

        Graphics2D g2 = output.createGraphics();
        g2.setComposite(AlphaComposite.Src);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.WHITE);
        g2.fillRoundRect(0, 0, w, h, cornerRadius, cornerRadius);

        g2.setComposite(AlphaComposite.SrcAtop);
        g2.drawImage(image, 0, 0, null);
        g2.dispose();

        return output;
    }

    /**
     * 将 Base64 字符串转换为临时文件
     *
     * @param base64String Base64 编码的图片数据
     * @return 临时文件对象
     */
    public static File convertBase64ToFile(String base64String) throws IOException {
        byte[] decodedBytes = Base64.getDecoder().decode(base64String);
        File tempFile = Files.createTempFile("avatar-", ".png").toFile();
        try (OutputStream os = Files.newOutputStream(tempFile.toPath())) {
            os.write(decodedBytes);
        }
        return tempFile;
    }
}

使用示例

#如果你只想要生成的base64文件
String imgBase64 = UserIdAvatarGeneratorUtil.generateImgBase64(userId);

#如果你想上传到云服务器比如阿里云oss,腾讯云cos
File temFile = null;
            try {
                temFile = UserIdAvatarGeneratorUtil.convertBase64ToFile(imgBase64);
            } catch (Exception e) {
                log.error("生成文件失败", e);
                throw new BusinessException(1, "生成文件失败");
            }
            String cosFilePath = CustomerConstants.REGISTER_USER_AVATAR_PATH + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "/";
            String newRegisterUserImgUrl = TencentUploadHelper.upload(temFile, cosFilePath, true);

看下效果

因为我里面的参数是,userId,所有图片中就是这个。

生成的图片背景色和数字是清晰的但是一些原因,我打码了。


网站公告

今日签到

点亮在社区的每一天
去签到