背景
最近需要写一个排行榜并生成海报分享朋友圈,记录一下,说不定以后能用到,生成玩文件可以自行选择是上传到OSS还是上传到本地服务器
我这边是通过企业微信推送图片,代码如果写的不好,请见谅,测试可以用
我这边使用Java的Graphics2D库来创建一个可视化的排行榜。在这个排行榜中,我们将显示一系列积分和排名。这个排行榜是生成的一张图片,可以用来分享
在开始编写代码之前,我们需要先确定排行榜的设计。排行榜可以是一个矩形区域,其中包含一个或多个排名榜单。每个排名榜单可以包含多个排名条目,每个条目表示一个人员的积分和排名。我们可以使用不同的颜色和字体样式来区分不同的元素。
在创建排行榜时,我们需要考虑以下因素:
-
排名:我们需要根据每个玩家的分数来计算其排名。我们可以使用一个简单的排序算法来排序玩家的分数,并将其分配到排名列表中。
-
积分数:我们需要显示每个玩家的分数。我们可以使用不同的颜色和字体来突出显示高分玩家,并使低分玩家的分数不那么显眼。
-
玩家名称:我们需要显示每个玩家的名称。我们可以使用不同的字体样式和颜色来突出显示玩家的名称,并使其与分数和排名区分开来。
-
排名图表:我们可以使用Graphics2D库来创建一个排名图表,显示每个玩家的排名随时间的变化。我们可以使用不同的颜色和样式来表示每个玩家,使得排名图表更加直观。
先看效果图
1.首先定一个常量类
/**
* @author c
* @date 2023/4/13 09:59
*/
public class PosterConstants {
public static String BACKGROUND_IMAGE = "https://xxx.com/rank/bg1.jpg";
}
2.定义一个画图的父类
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* @author c
* @date 2023/4/13 09:13
*/
public abstract class AbstractDrawPoster<T> {
Graphics2D graphics2D = null;
/**
* 内容颜色
*/
private Color contentColor = new Color(0, 0, 0);
/**
* 标题颜色
*/
private Color titleColor = new Color(0, 0, 0);
/**
* 具体左边距离
*/
private int contentMarginLeft = 60;
/**
* 距离顶部距离
*/
private int contentMarginTop = 700;
/**
* 每一列的宽度
*/
private int rowWidth = 220;
/**
* 每一列的高度
*/
private int rowHeight = 55;
/**
* 内容用到的字体 加粗方式 字号
*/
private Font contentFont = new Font("思源宋体 CN", Font.BOLD, 33);
/**
* 标题用到的字体 加粗方式 字号
*/
private Font titleFont = new Font("思源宋体 CN", Font.BOLD, 33);
/**
* 标题距离顶部的距离
*/
private int titleMarginTop = 650;
/**
* 背景图
*/
BufferedImage backgroundImage = null;
BufferedImage poster = null;
/**
* 设置标题距离顶部距离
*
* @param titleMarginTop
*/
public void setTitleMarginTop(int titleMarginTop) {
this.titleMarginTop = titleMarginTop;
}
private String backgroundImgUrl;
List<List<String>> listData = null;
public void addData(List<String> list) {
if (listData == null) {
listData = new ArrayList<>();
}
listData.add(list);
}
/**
* 生成图片
*
* @param t
* @param title
* @return
* @throws IOException
*/
public File generateImage(T t, String title) throws IOException {
dataProcessor(t);
initBackground();
setTitle(title);
setContent();
//File outputFile = File.createTempFile(UUID.randomUUID().toString(), null);
File outputFile = new File("/Users/Desktop/temp/poster11.jpg");
ImageIO.write(poster, "jpg", outputFile);
return outputFile;
}
/**
* 填充数据
*
* @param t
* @return
*/
public abstract void dataProcessor(T t);
/**
* @param x 列表距离左边的距离
* @param y 列表距离顶部的距离
*/
public void setMargin(int x, int y) {
this.contentMarginLeft = x;
this.contentMarginTop = y;
}
/**
* 设置每一列的宽高
*
* @param width
* @param height
*/
public void setWidthAndHeight(int width, int height) {
this.rowWidth = width;
this.rowHeight = height;
}
/**
* 设置内容字体颜色
*
* @param contentColor
*/
public void setContentColor(Color contentColor) {
this.contentColor = contentColor;
}
/**
* 设置标题字体颜色
*
* @param titleColor
*/
public void setTitleColor(Color titleColor) {
this.titleColor = titleColor;
}
/**
* 设置内容字体大小
*
* @param contentFont
*/
public void setContentFont(Font contentFont) {
this.contentFont = contentFont;
}
/**
* 设置标题字体大小
*
* @param titleFont
*/
public void setTitleFont(Font titleFont) {
this.titleFont = titleFont;
}
/**
* 设置背景图片
*
* @param backgroundImgUrl
*/
public void setBackgroundImgUrl(String backgroundImgUrl) {
this.backgroundImgUrl = backgroundImgUrl;
}
/**
* 初始化背景
* @throws IOException
*/
public void initBackground() throws IOException {
backgroundImage = ImageIO.read(new URL(backgroundImgUrl));
poster = new BufferedImage(backgroundImage.getWidth(), backgroundImage.getHeight(), BufferedImage.TYPE_INT_RGB);
graphics2D = poster.createGraphics();
graphics2D.drawImage(backgroundImage, 0, 0, null);
}
/**
* 设置标题
* @param title
*/
public void setTitle(String title) {
graphics2D.setFont(titleFont);
graphics2D.setColor(titleColor);
FontMetrics fm1 = graphics2D.getFontMetrics();
int stringWidth1 = fm1.stringWidth(title);
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int centerX1 = (backgroundImage.getWidth() - stringWidth1) / 2;
graphics2D.drawString(title, centerX1, titleMarginTop);
}
/**
*设置内容
*/
public void setContent() {
int numColumns = listData.size();
int numRows = listData.get(0).size();
graphics2D.setFont(contentFont);
graphics2D.setColor(contentColor);
for (int i = 0; i < numColumns; i++) {
int y = contentMarginTop + i * rowHeight;
for (int j = 0; j < numRows; j++) {
int x = contentMarginLeft + j * rowWidth;
String data = listData.get(i).get(j);
int stringWidth = getFontWidth(data);
int centerX = x + (rowWidth - stringWidth) / 2;
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.drawString(data, centerX, y);
}
}
}
/**
* 获取单个内容的宽度
* @param data
* @return
*/
public int getFontWidth(String data) {
FontMetrics fm = graphics2D.getFontMetrics();
return fm.stringWidth(data);
}
}
3.定义实现类:
import com.jch.common.constant.PosterConstants;
import com.jch.order.dto.TherapistDTO;
import com.jch.order.entity.UnitPriceEntity;
import com.jch.service.draw.AbstractDrawPoster;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author c
* @date 2023/4/13 09:57
*/
@Service
@Slf4j
public class RankDrawPoster extends AbstractDrawPoster<Object> {
@Override
public void dataProcessor(Object unitPriceEntity) {
setBackgroundImgUrl(PosterConstants.BACKGROUND_IMAGE);
setHeader();
mockData();
}
public void setHeader() {
List<String> column = new ArrayList<>();
column.add("排名");
column.add("姓名");
column.add("总积分");
addData(column);
}
public void mockData() {
for (int i = 5; i > 0; i--) {
List<String> column = new ArrayList<>();
column.add(String.valueOf(i + 1));
column.add("张三" + i);
column.add(String.valueOf(i * 10));
addData(column);
}
}
public static void main(String[] args) throws IOException {
RankDrawPoster rankDrawPoster= new RankDrawPoster();
rankDrawPoster.generateImage(new Object(),"积分排行榜");
}
}
如果有更好的写法也可以分享给我,我可以学习一下
总之,使用Java的Graphics2D库可以非常方便地创建一个可视化的排行榜