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