Java生成海报案例怎么写

wen java案例 5

本文目录导读:

Java生成海报案例怎么写

  1. 方式一:使用Java Graphics2D绘制海报
  2. 方式二:使用Thumbnailator库生成海报
  3. 方式三:使用FreeMarker模板 + 服务端渲染
  4. 最佳实践建议

我来为你提供一个完整的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的高级特性。

抱歉,评论功能暂时关闭!