本文目录导读:

我来为你提供一个完整的Java生成海报案例,这里我将展示两种常见的方式:使用Graphics2D绘制和使用第三方库。
使用Java Graphics2D绘制海报
基础海报生成类
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/**
* 海报生成工具类
*/
public class PosterGenerator {
/**
* 生成产品推广海报
*/
public static void generateProductPoster(String productName,
String price,
String qrCodeUrl,
String backgroundImageUrl,
String outputPath) throws IOException {
// 1. 创建画布 (750x1334 是常见手机海报尺寸)
int width = 750;
int height = 1334;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
// 2. 设置抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// 3. 绘制背景
drawBackground(g2d, width, height, backgroundImageUrl);
// 4. 绘制商品信息区域
drawProductInfo(g2d, productName, price, width, height);
// 5. 绘制二维码区域
drawQRCode(g2d, qrCodeUrl, width, height);
// 6. 释放资源
g2d.dispose();
// 7. 保存图片
File outputFile = new File(outputPath);
ImageIO.write(image, "png", outputFile);
System.out.println("海报生成成功: " + outputPath);
}
/**
* 绘制背景
*/
private static void drawBackground(Graphics2D g2d, int width, int height, String bgImageUrl) {
try {
if (bgImageUrl != null && !bgImageUrl.isEmpty()) {
// 使用网络图片作为背景
BufferedImage bgImage = ImageIO.read(new URL(bgImageUrl));
g2d.drawImage(bgImage, 0, 0, width, height, null);
} else {
// 使用渐变背景
GradientPaint gradient = new GradientPaint(
0, 0, new Color(255, 182, 193),
width, height, new Color(255, 105, 180)
);
g2d.setPaint(gradient);
g2d.fillRect(0, 0, width, height);
}
} catch (Exception e) {
// 如果加载失败,使用纯色背景
g2d.setColor(new Color(255, 240, 245));
g2d.fillRect(0, 0, width, height);
}
}
/**
* 绘制商品信息
*/
private static void drawProductInfo(Graphics2D g2d, String productName, String price, int width, int height) {
// 产品名称
g2d.setColor(Color.WHITE);
g2d.setFont(new Font("微软雅黑", Font.BOLD, 36));
FontMetrics metrics = g2d.getFontMetrics();
int textWidth = metrics.stringWidth(productName);
int x = (width - textWidth) / 2;
g2d.drawString(productName, x, 200);
// 价格
g2d.setColor(new Color(255, 215, 0)); // 金色
g2d.setFont(new Font("微软雅黑", Font.BOLD, 48));
String priceText = "¥ " + price;
metrics = g2d.getFontMetrics();
textWidth = metrics.stringWidth(priceText);
x = (width - textWidth) / 2;
g2d.drawString(priceText, x, 280);
// 副标题
g2d.setColor(Color.WHITE);
g2d.setFont(new Font("微软雅黑", Font.PLAIN, 24));
String subTitle = "限时特惠 赶快抢购";
metrics = g2d.getFontMetrics();
textWidth = metrics.stringWidth(subTitle);
x = (width - textWidth) / 2;
g2d.drawString(subTitle, x, 350);
}
/**
* 绘制二维码区域
*/
private static void drawQRCode(Graphics2D g2d, String qrCodeUrl, int width, int height) {
// 绘制白色背景
int qrSize = 200;
int qrX = (width - qrSize) / 2;
int qrY = height - qrSize - 150;
// 绘制圆角矩形背景
g2d.setColor(Color.WHITE);
g2d.fillRoundRect(qrX - 10, qrY - 10, qrSize + 20, qrSize + 20, 20, 20);
// 绘制提示文字
g2d.setColor(Color.GRAY);
g2d.setFont(new Font("微软雅黑", Font.PLAIN, 20));
String tip = "长按识别二维码";
FontMetrics metrics = g2d.getFontMetrics();
int textWidth = metrics.stringWidth(tip);
int textX = (width - textWidth) / 2;
g2d.drawString(tip, textX, qrY - 30);
// 这里可以加载真实的二维码图片
// 如果没有,画一个占位符
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillRect(qrX, qrY, qrSize, qrSize);
g2d.setColor(Color.DARK_GRAY);
g2d.setFont(new Font("微软雅黑", Font.PLAIN, 16));
String placeholder = "二维码区域";
metrics = g2d.getFontMetrics();
textWidth = metrics.stringWidth(placeholder);
textX = qrX + (qrSize - textWidth) / 2;
g2d.drawString(placeholder, textX, qrY + qrSize / 2);
}
/**
* 添加文字水印
*/
public static void addWatermark(BufferedImage image, String watermark) {
Graphics2D g2d = image.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 设置水印样式
g2d.setColor(new Color(255, 255, 255, 100));
g2d.setFont(new Font("微软雅黑", Font.BOLD, 20));
// 计算文字位置
FontMetrics metrics = g2d.getFontMetrics();
int x = image.getWidth() - metrics.stringWidth(watermark) - 20;
int y = image.getHeight() - 20;
// 绘制水印
g2d.drawString(watermark, x, y);
g2d.dispose();
}
/**
* 生成带圆角的头像
*/
public static BufferedImage createRoundedImage(BufferedImage image, int cornerRadius) {
int w = image.getWidth();
int h = image.getHeight();
BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = output.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setClip(new RoundRectangle2D.Float(0, 0, w, h, cornerRadius, cornerRadius));
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
return output;
}
}
主程序调用示例
public class PosterDemo {
public static void main(String[] args) {
try {
// 生成海报
PosterGenerator.generateProductPoster(
"精美礼品套装",
"299.00",
"https://example.com/qrcode.png",
"https://example.com/background.jpg",
"poster.png"
);
System.out.println("海报生成完成!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用Thumbnailator库生成海报
添加Maven依赖
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.20</version>
</dependency>
使用Thumbnailator生成海报
import net.coobird.thumbnailator.Thumbnails;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
public class ThumbnailPosterGenerator {
public static void generatePoster() throws Exception {
// 创建空白画布
int width = 750;
int height = 1334;
BufferedImage poster = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = poster.createGraphics();
// 设置背景
g2d.setColor(new Color(255, 240, 245));
g2d.fillRect(0, 0, width, height);
// 添加文字
g2d.setColor(Color.BLACK);
g2d.setFont(new Font("微软雅黑", Font.BOLD, 32));
g2d.drawString("促销活动", width/2 - 100, 100);
// 添加图片(如果有)
// BufferedImage productImage = ImageIO.read(new File("product.jpg"));
// g2d.drawImage(productImage, 100, 150, 550, 550, null);
g2d.dispose();
// 保存图片
ImageIO.write(poster, "png", new File("poster_with_thumbnailator.png"));
}
}
使用FreeMarker模板 + 服务端渲染
添加依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.32</version>
</dependency>
创建HTML模板
<!DOCTYPE html>
<html>
<head>
<style>
.poster-container {
width: 750px;
height: 1334px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 30px;
box-sizing: border-box;
font-family: 'Microsoft YaHei', sans-serif;
}
.product-box {
background: white;
border-radius: 20px;
padding: 20px;
text-align: center;
}
.product-name {
font-size: 36px;
color: #333;
margin-bottom: 10px;
}
.product-price {
font-size: 48px;
color: #ff6b6b;
font-weight: bold;
}
.qr-code {
width: 200px;
height: 200px;
background: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
}
</style>
</head>
<body>
<div class="poster-container">
<div class="product-box">
<h1 class="product-name">${productName}</h1>
<p class="product-price">¥ ${price}</p>
<p>${description}</p>
</div>
<div class="qr-code">
二维码占位
</div>
</div>
</body>
</html>
完整的企业级解决方案
/**
* 更完整的海报生成服务
*/
@Service
public class PosterService {
/**
* 生成用户分享海报
*/
public String generateSharePoster(ShareData data) {
try {
// 1. 创建画布
int width = 750;
int height = 1334;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = image.createGraphics();
// 2. 设置高质量渲染
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
// 3. 绘制各元素
drawHeader(g2d, data);
drawUserInfo(g2d, data);
drawContent(g2d, data);
drawQRCode(g2d, data);
drawFooter(g2d, data);
// 4. 释放资源
g2d.dispose();
// 5. 保存到OSS或本地
String path = saveToServer(image);
return path;
} catch (Exception e) {
logger.error("生成海报失败", e);
throw new BusinessException("海报生成失败");
}
}
/**
* 绘制头部
*/
private void drawHeader(Graphics2D g2d, ShareData data) {
// 绘制logo
g2d.setColor(Color.WHITE);
g2d.setFont(new Font("微软雅黑", Font.BOLD, 40));
g2d.drawString("品牌名称", 30, 80);
// 绘制边框
g2d.setStroke(new BasicStroke(3));
g2d.setColor(new Color(255, 255, 255, 150));
g2d.drawLine(30, 100, 720, 100);
}
/**
* 保存图片到服务器
*/
private String saveToServer(BufferedImage image) throws IOException {
// 生成唯一文件名
String fileName = UUID.randomUUID().toString() + ".png";
String path = "/tmp/posters/" + fileName;
File file = new File(path);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
ImageIO.write(image, "png", file);
return path;
}
/**
* 数据类
*/
public static class ShareData {
private String userName;
private String avatarUrl;
private String productName;
private String price;
private String qrCodeContent;
private String backgroundUrl;
// getter/setter...
}
}
最佳实践建议
内存优化
// 使用合适的图片类型 BufferedImage.TYPE_INT_RGB // 不透明 BufferedImage.TYPE_INT_ARGB // 透明 // 及时释放 g2d.dispose(); image.flush();
字体处理
// 加载自定义字体
InputStream fontStream = getClass().getResourceAsStream("/fonts/msyh.ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, fontStream);
font = font.deriveFont(Font.BOLD, 24f);
错误处理
try {
// 生成逻辑
} catch (IOException e) {
logger.error("图片读取错误", e);
} catch (Exception e) {
logger.error("海报生成异常", e);
} finally {
// 清理资源
}
这个方案提供了完整的海报生成功能,你可以根据实际需求选择合适的实现方式,如果需要更复杂的功能,如添加图层合成、滤镜效果等,可以考虑使用专业的图像处理库如OpenCV或Java 2D的高级特性。