本文目录导读:

我来为你提供一个完整的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的高级特性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播