【Java后端生成海报模板代码】

本文介绍了如何使用Java后端技术,结合Spring框架,实现动态生成海报模板的代码实现过程,包括关键步骤和示例代码。
package com.zhl.tour.hypermarket.goods.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.StrUtil;
import com.github.jaiimageio.impl.common.ImageUtil;
import com.zhl.tour.common.api.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.poi.ss.util.ImageUtils;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.test.context.TestConstructor;
import org.springframework.test.context.event.annotation.AfterTestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.xml.bind.DatatypeConverter;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.*;
import java.net.URL;

/**
 * @ClassName: LoadPosterUtils
 * @author: 7
 * @date: 2022/6/15 14:22
 */

@SuppressWarnings("all")
@Slf4j
@Component
public class LoadPosterImages {

    public static void main(String[] args) throws IOException {
        String backGround = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F911%2F0H215092042%2F150H2092042-5-1200.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1657950966&t=c03743c9e9f3c611d2f7229743afecc7";


        String coding = "https://img0.baidu.com/it/u=3066154895,922262853&fm=253&fmt=auto&app=138&f=JPEG?w=260&h=260";

        //获取64编码后的 图片
        String encode = Base64.encode(coding);

        MultipartFile result = biuldPoster(backGround, encode, "张三", "template_product_10.png");
        InputStream inputStream = result.getInputStream();
        System.err.println(result.getName());


    }


    /**
     *
     */
    private static final String imageFormat = "png";
    private static String produt = "";
    private static String shop = "";

    static {
        produt = "";
        shop = "";
    }


    /**
     * @param posterImage       海报图片
     * @param qrcodeImageBase64 小程序二维码
     * @param userName          用户昵称
     * @return 文件
     */
    public static MultipartFile biuldPoster(String posterImage, String qrcodeImageBase64, String userName, String templateFileName) {
        if (StrUtil.isBlank(posterImage) || StrUtil.isBlank(qrcodeImageBase64) || StrUtil.isBlank(userName)) {
            log.error("构建小程序海报参数错误:{}", posterImage, qrcodeImageBase64, userName);
            throw new IllegalArgumentException("参数异常请检查参数!!!");
        }
        try {

            //裁剪好背景图片
            Image img = createThumbnail2(posterImage, imageFormat, 860, 860);


            //解码
            String coding = Base64.decodeStr(qrcodeImageBase64);
            //裁剪好二维码图片
//            Image codeimgIconImage = resizePng(coding, imageFormat, 150, 150, false);
            Image codeimgIconImage = resizePng(coding, 150, 150, false);

            //获取模板图片
            URL url = new ClassPathResource("template/" + templateFileName).getUrl();
            Image src = Toolkit.getDefaultToolkit().getImage(url);
            BufferedImage buffImg = toBufferedImage(src);

            //得到画笔对象
            Graphics g = buffImg.getGraphics();


            //将小图片绘到大图片上。
            g.drawImage(img, 20, 20, null);
            g.setColor(Color.GRAY.brighter());

            // 绘制原型对话框
            g.drawRoundRect(155, 750, 605, 65, 30, 25);
            g.setColor(Color.white);

            //二维码绘制到大图上去
            g.drawImage(codeimgIconImage, 710, 915, null);

            //设置字体及字体颜色大小
            Font font = new Font("黑体", Font.BOLD, 25); // 创建字体对象
            g.setFont(font);
            g.drawString("@".concat(userName), 160, 789);
            g.dispose();
            //输出地址
            String shareFileName = System.currentTimeMillis() + ".jpg";

            FileItemFactory factory = new DiskFileItemFactory(16, null);
            String textFieldName = "file";
            FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, shareFileName);

            // ImageBuffer 转换成输出流
            OutputStream os = item.getOutputStream();
            ImageIO.write(buffImg, "jpg", os);
            os.close();

            // 输出流 转换 MultipartFile 返回
            return new CommonsMultipartFile(item);

        } catch (Exception e) {
            log.error("模板生成模板失败:{}", e, e.getMessage());
        }
        throw new BizException("构建app图片失败----");
    }
    

    // 互联网地址的图片 转换成 BufferedImage
    public static BufferedImage createThumbnail2(String fromFileStr, String suffix, int width, int height) throws Exception {
        try {
            URL urlfile = new URL(fromFileStr);
            InputStream inputStream = urlfile.openStream();
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            int bytesRead = 0;
            byte[] temp = new byte[8192];
            while ((bytesRead = inputStream.read(temp, 0, 8192)) != -1) {
                output.write(temp, 0, bytesRead);
            }
            byte[] data = output.toByteArray();
            inputStream.close();
            output.close();

            Image src = Toolkit.getDefaultToolkit().createImage(data);
            BufferedImage buffer = toBufferedImage(src);

            /*
             * 核心算法,计算图片的压缩比
             */
            int w = buffer.getWidth();
            int h = buffer.getHeight();
            double ratiox = 1.0d;
            double ratioy = 1.0d;

            ratiox = w * ratiox / width;
            ratioy = h * ratioy / height;

            if (ratiox >= 1) {
                if (ratioy < 1) {
                    ratiox = height * 1.0 / h;
                } else {
                    if (ratiox > ratioy) {
                        ratiox = height * 1.0 / h;
                    } else {
                        ratiox = width * 1.0 / w;
                    }
                }
            } else {
                if (ratioy < 1) {
                    if (ratiox > ratioy) {
                        ratiox = height * 1.0 / h;
                    } else {
                        ratiox = width * 1.0 / w;
                    }
                } else {
                    ratiox = width * 1.0 / w;
                }
            }
            /*
             * 对于图片的放大或缩小倍数计算完成,ratiox大于1,则表示放大,否则表示缩小
             */
            AffineTransformOp op = new AffineTransformOp(AffineTransform
                    .getScaleInstance(ratiox, ratiox), null);
            buffer = op.filter(buffer, null);
            //从放大的图像中心截图
//        buffer = buffer.getSubimage((buffer.getWidth() - width) / 2, (buffer.getHeight() - height) / 2, width, height);
            buffer = buffer.getSubimage((buffer.getWidth() - width) / 2, (buffer.getHeight() - height) / 2, width, height);
            //写入文件

            return buffer;
        } catch (Exception e) {
            log.error("格式化图片时发生异常{}", e, e.getMessage());
            // e.printStackTrace();
            return null;
        }
    }


    public static File convertFileByUrl(String url) {
        File file = null;

        URL urlfile;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            file = File.createTempFile("wx_image", ".png");
            //下载
            urlfile = new URL(url);
            inputStream = urlfile.openStream();
            outputStream = new FileOutputStream(file);

            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != outputStream) {
                    outputStream.close();
                }
                if (null != inputStream) {
                    inputStream.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    public static BufferedImage toBufferedImage(Image image) {
        BufferedImage bimage = null;
        try {
            if (image instanceof BufferedImage) {
                return (BufferedImage) image;
            }
            // This code ensures that all the pixels in the image are loaded
            image = new ImageIcon(image).getImage();
            bimage = null;
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            try {
                int transparency = Transparency.OPAQUE;
                GraphicsDevice gs = ge.getDefaultScreenDevice();
                GraphicsConfiguration gc = gs.getDefaultConfiguration();

                int wd = image.getWidth(null) == -1 ? 900 : image.getWidth(null);

                int hg = image.getHeight(null) == -1 ? 1100 : image.getHeight(null);

                BufferedImage bi = new BufferedImage(wd, hg, BufferedImage.TYPE_INT_RGB);

                Graphics2D big = bi.createGraphics();

                big.drawImage(image, 10, 10, null);


                bimage = gc.createCompatibleImage(wd, hg, transparency);
            } catch (HeadlessException e) {
                // The system does not have a screen
            }
            if (bimage == null) {
                // Create a buffered image using the default color model
                int type = BufferedImage.TYPE_INT_RGB;
                bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
            }
            Graphics g = bimage.createGraphics();

            g.drawImage(image, 0, 0, null);
            g.dispose();
        } catch (Exception e) {
            log.error("裁剪图片时发生异常----", e, e.getMessage());
            e.printStackTrace();
        }
        return bimage;
    }


    /**
     * 裁剪PNG图片工具类
     *
     * @param fromFile     源文件
     * @param toFile       裁剪后的文件
     * @param outputWidth  裁剪宽度
     * @param outputHeight 裁剪高度
     * @param proportion   是否是等比缩放
     */
    public static BufferedImage resizePng(String url, int outputWidth, int outputHeight,
                                          boolean proportion) {
        try {
            URL urlfile = new URL(url);
            InputStream inputStream = urlfile.openStream();
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            int bytesRead = 0;
            byte[] temp = new byte[8192];
            while ((bytesRead = inputStream.read(temp, 0, 8192)) != -1) {
                output.write(temp, 0, bytesRead);
            }
            byte[] data = output.toByteArray();
            inputStream.close();
            output.close();

            Image src = Toolkit.getDefaultToolkit().createImage(data);
            BufferedImage bi2 = toBufferedImage(src);


//            BufferedImage bi2 = ImageIO.read(fromFile);
            int newWidth;
            int newHeight;
            // 判断是否是等比缩放
            if (proportion) {
                // 为等比缩放计算输出的图片宽度及高度
                double rate1 = ((double) bi2.getWidth(null)) / (double) outputWidth + 0.1;
                double rate2 = ((double) bi2.getHeight(null)) / (double) outputHeight + 0.1;
                // 根据缩放比率大的进行缩放控制
                double rate = rate1 < rate2 ? rate1 : rate2;
                newWidth = (int) (((double) bi2.getWidth(null)) / rate);
                newHeight = (int) (((double) bi2.getHeight(null)) / rate);
            } else {
                newWidth = outputWidth; // 输出的图片宽度
                newHeight = outputHeight; // 输出的图片高度
            }
            BufferedImage to = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = to.createGraphics();
            to = g2d.getDeviceConfiguration().createCompatibleImage(newWidth, newHeight,
                    Transparency.TRANSLUCENT);
            g2d.dispose();
            g2d = to.createGraphics();
            @SuppressWarnings("static-access")
            Image from = bi2.getScaledInstance(newWidth, newHeight, bi2.SCALE_AREA_AVERAGING);
            g2d.drawImage(from, 0, 0, null);
            g2d.dispose();
            return to;
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new BizException("...");
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值