This commit is contained in:
王鹏
2025-08-14 14:57:00 +08:00
commit 9122dabf88
830 changed files with 90569 additions and 0 deletions

View File

@@ -0,0 +1,194 @@
package com.ruoyi.common.utils;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.util.Random;
import javax.imageio.ImageIO;
public class CoverGenerator {
private static final Color[][] COLOR_SCHEMES = {
// 绿色系
{new Color(0, 128, 0)}, // 绿色
{new Color(46, 139, 87)}, // 海洋绿
{new Color(60, 179, 113)}, // 中海洋绿
{new Color(32, 178, 170)}, // 浅海洋绿
{new Color(0, 106, 78)}, // 深森林绿
{new Color(0, 139, 69)}, // 春绿
{new Color(34, 139, 34)}, // 森林绿
{new Color(50, 205, 50)}, // 酸橙绿
{new Color(0, 128, 128)}, // 水鸭绿
// 蓝色系
{new Color(70, 130, 180)}, // 钢青色
{new Color(95, 158, 160)}, // 暗青色
{new Color(100, 149, 237)}, // 矢车菊蓝
{new Color(25, 25, 112)}, // 午夜蓝
{new Color(0, 0, 139)}, // 深蓝色
{new Color(30, 144, 255)}, // 道奇蓝
{new Color(65, 105, 225)}, // 皇家蓝
{new Color(0, 191, 255)}, // 深天蓝
// 紫色系
{new Color(106, 90, 205)}, // 石板蓝
{new Color(123, 104, 238)}, // 中紫色
{new Color(72, 61, 139)}, // 暗紫色
{new Color(138, 43, 226)}, // 紫罗兰
{new Color(148, 0, 211)}, // 暗紫罗兰
{new Color(153, 50, 204)}, // 深兰花紫
// 青色系
{new Color(0, 139, 139)}, // 深青色
{new Color(0, 206, 209)}, // 深绿松石
{new Color(72, 209, 204)}, // 中绿松石
{new Color(64, 224, 208)}, // 绿松石
// 灰色系
{new Color(47, 79, 79)}, // 暗岩灰
{new Color(105, 105, 105)}, // 暗灰
{new Color(112, 128, 144)}, // 石板灰
{new Color(119, 136, 153)}, // 浅石板灰
// 褐色系
{new Color(139, 69, 19)}, // 马鞍棕色
{new Color(160, 82, 45)}, // 赭色
{new Color(165, 42, 42)}, // 褐色
{new Color(128, 0, 0)}, // 栗色
// 其他优雅配色
{new Color(85, 107, 47)}, // 暗橄榄绿
{new Color(107, 142, 35)}, // 橄榄土褐色
{new Color(143, 188, 143)}, // 暗海绿
{new Color(176, 196, 222)}, // 浅钢蓝
{new Color(176, 224, 230)} // 粉蓝色
};
private static Color getRandomColor() {
Random random = new Random();
return COLOR_SCHEMES[random.nextInt(COLOR_SCHEMES.length)][0];
}
private static void addSubtleShadow(Graphics2D g2d, String text, int x, int y, Font font, Color shadowColor) {
int offset = 2;
// 第一层阴影,较淡
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.12f));
g2d.setColor(shadowColor);
g2d.drawString(text, x + offset, y + offset);
// 第二层阴影,稍深
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f));
g2d.drawString(text, x + offset - 1, y + offset - 1);
// 重置透明度
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
}
// 添加字体加载逻辑
private static Font loadFont(int size) {
try {
// 优先尝试加载项目内部的字体文件
InputStream is = CoverGenerator.class.getResourceAsStream("/fonts/SimHei.ttf");
if (is != null) {
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
return font.deriveFont(Font.BOLD, size);
}
} catch (Exception e) {
// 记录日志但继续执行
System.out.println("Failed to load custom font: " + e.getMessage());
}
// fallback到系统字体
return new Font("Dialog.plain", Font.BOLD, size);
}
public static BufferedImage createCover(String text1, String text2, String tagText, int titleSize) {
int width = 1200;
int height = 675;
// 创建图片
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = image.createGraphics();
// 设置背景色
Color bgColor = getRandomColor();
g2d.setColor(bgColor);
g2d.fillRect(0, 0, width, height);
// 启用抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// 修改字体设置部分
Font titleFont = loadFont(60);
Font subtitleFont = loadFont(titleSize);
Font tagFont = loadFont(35);
// 计算文字位置
FontMetrics titleMetrics = g2d.getFontMetrics(titleFont);
int titleWidth = titleMetrics.stringWidth(text1);
int titleX = (width - titleWidth) / 2;
int titleY = height / 6 + titleMetrics.getAscent();
FontMetrics subtitleMetrics = g2d.getFontMetrics(subtitleFont);
int subtitleWidth = subtitleMetrics.stringWidth(text2);
int subtitleX = (width - subtitleWidth) / 2;
int subtitleY = height / 2 - 60 + subtitleMetrics.getAscent();
// 绘制主标题
g2d.setFont(titleFont);
addSubtleShadow(g2d, text1, titleX, titleY, titleFont, Color.BLACK);
g2d.setColor(Color.WHITE);
g2d.drawString(text1, titleX, titleY);
// 绘制副标题
g2d.setFont(subtitleFont);
addSubtleShadow(g2d, text2, subtitleX, subtitleY, subtitleFont, Color.BLACK);
g2d.setColor(new Color(255, 223, 128));
g2d.drawString(text2, subtitleX, subtitleY);
// 绘制标签
g2d.setFont(tagFont);
FontMetrics tagMetrics = g2d.getFontMetrics(tagFont);
int tagWidth = tagMetrics.stringWidth(tagText);
int tagHeight = tagMetrics.getHeight();
int tagX = (width - tagWidth) / 2;
int tagY = height * 3 / 4 + tagMetrics.getAscent();
// 绘制标签背景
int paddingX = 30;
int paddingY = 15;
g2d.setColor(new Color(255, 223, 128));
g2d.fillRoundRect(
tagX - paddingX,
tagY - tagMetrics.getAscent() - paddingY,
tagWidth + paddingX * 2,
tagHeight + paddingY * 2,
20,
20
);
// 绘制标签文字
g2d.setColor(Color.BLACK);
g2d.drawString(tagText, tagX, tagY);
g2d.dispose();
return image;
}
public static void main(String[] args) {
try {
String title = "SpringBoot + Vue2";
String subtitle = "二手手机管理系统";
String tagText = "源码 + 数据库 + 论文";
int titleSize = 120;
BufferedImage cover = createCover(title, subtitle, tagText, titleSize);
ImageIO.write(cover, "PNG", new File("cover.png"));
System.out.println("Cover image generated successfully!");
} catch (Exception e) {
e.printStackTrace();
}
}
}