Java实现文字图片
编写工具类
@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,所有图片中就是这个。
生成的图片背景色和数字是清晰的但是一些原因,我打码了。