JAVA 創建帶個人信息,頭像等內容和可變二維碼的海報

JAVA 創建帶個人信息,頭像等內容和可變二維碼的海報


1、添加二維碼依賴包

        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.3.0</version>
        </dependency>

2、寫畫圖工具類


import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.zyfycs.college.plugin.alibaba.oss.OSS;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Created by 譚健 on 2020/4/23. 星期四. 10:42.
 * © All Rights Reserved.
 */

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ImageDrawUtils {


    /**
     * 畫一個海報
     */
    public static void drawPoster() throws IOException, WriterException {


        // 創建背景
        BufferedImage backgroundImage = createImage("https://csxy-public-img.oss-cn-hangzhou.aliyuncs.com/other/timg.jpg");
        // 創建頭像
        BufferedImage filletImage = fillet(createImage("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1587634370462&di=80a37d1fed5581e4d25d9507322a0324&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201802%2F20%2F20180220165946_RiGPS.thumb.700_0.jpeg"), 120, 120);
        // 創建二維碼
        BufferedImage qrCodeImage = createQrCodeImage("https://www.baidu.com/", 200, 200);

        // 創建畫布
        BufferedImage canvas = new BufferedImage(backgroundImage.getWidth(), backgroundImage.getHeight(), BufferedImage.TYPE_INT_RGB);
        // 初始化背景
        Graphics2D graphics = setBackground(canvas, backgroundImage);

        // 把背景畫上去
        imageDraw(graphics, new ImageDraw(backgroundImage, 0, 0, backgroundImage.getWidth(), backgroundImage.getHeight()));
        // 把頭像畫上去
        imageDraw(graphics, new ImageDraw(filletImage, 70, 70, 150, 150));
        // 把二維碼畫上去
        imageDraw(graphics, new ImageDraw(qrCodeImage, 730, 1250, 200, 200));
        graphics.dispose();

        OSS.simpleUpload(toInputStream(canvas), "png", "other/", UUID.absolutelyUniqueId());
    }


    /**
     * 設置背景圖片
     *
     * @param canvas          畫布
     * @param backgroundImage 背景圖
     * @return
     */
    public static Graphics2D setBackground(BufferedImage canvas, BufferedImage backgroundImage) {
        Graphics2D graphics = (Graphics2D) canvas.getGraphics();
        // 抗鋸齒
        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
        imageDraw(graphics, new ImageDraw(backgroundImage, 0, 0, backgroundImage.getWidth(), backgroundImage.getHeight()));
        return graphics;
    }


    /**
     * 給圖片設置圓角,並留一個白色外圈,用於頭像圓角化
     */
    public static BufferedImage fillet(BufferedImage image, int width, int height) {

        // 一張空白圖片
        BufferedImage blankImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D graphics = newCanvas(blankImage);

        // 留一像素的空白區域
        int border = 1;
        Ellipse2D.Double shape = new Ellipse2D.Double(border, border, width - border * 2, width - border * 2);
        graphics.setClip(shape);
        graphics.drawImage(image, border, border, width - border * 2, width - border * 2, null);
        graphics.dispose();

        graphics = newCanvas(blankImage);
        int roundBorder = 3;
        // 畫筆是4.5個像素,BasicStroke的使用可以查看下面的參考文檔
        // 使畫筆時基本會像外延伸一定像素,具體可以自己使用的時候測試
        Stroke s = new BasicStroke(4.5F, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        graphics.setStroke(s);
        graphics.setColor(Color.WHITE);
        graphics.drawOval(roundBorder, roundBorder, width - roundBorder * 2, width - roundBorder * 2);
        graphics.dispose();

        return blankImage;
    }


    private static Graphics2D newCanvas(BufferedImage image) {
        Graphics2D graphics = image.createGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        return graphics;
    }


    /**
     * 把畫布轉成 InputStream 流
     *
     * @param canvas 畫布
     * @return
     * @throws IOException
     */
    public static InputStream toInputStream(BufferedImage canvas) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(canvas, "png", os);
        return new ByteArrayInputStream(os.toByteArray());
    }

    /**
     * 圖片繪製對象
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private static class ImageDraw {

        /**
         * 圖片
         */
        private BufferedImage image;
        /**
         * x軸偏移量
         */
        private int x;
        /**
         * y軸偏移量
         */
        private int y;
        /**
         * 寬度
         */
        private int width;
        /**
         * 高度
         */
        private int height;

    }


    /**
     * 文本繪製對象
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private static class StringDraw {
        /**
         * 文本類型
         */
        private String text;
        /**
         * x軸偏移量
         */
        private int x;
        /**
         * y軸偏移量
         */
        private int y;

        /**
         * 顏色
         */
        private Color color;
        /**
         * 文字樣式
         */
        private Font font;
    }


    /**
     * 創建背景圖像
     */
    public static BufferedImage createImage(String ImageUrl) throws IOException {
        return ImageIO.read(new URL(ImageUrl));
    }

    /**
     * 創建畫布
     */
    public static Graphics2D createCanvas(BufferedImage backgroundImage) {
        BufferedImage canvas = new BufferedImage(backgroundImage.getWidth(), backgroundImage.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = (Graphics2D) canvas.getGraphics();
        // 抗鋸齒
        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
        return graphics;
    }


    /**
     * 繪製圖片
     *
     * @param canvas   畫布
     * @param drawInfo 圖片信息
     */
    public static void imageDraw(Graphics2D canvas, Object drawInfo) {
        ImageDraw imageDraw = (ImageDraw) drawInfo;
        canvas.drawImage(imageDraw.getImage().getScaledInstance(imageDraw.getWidth(), imageDraw.getHeight(), Image.SCALE_DEFAULT), imageDraw.getX(), imageDraw.getY(), null);
    }


    /**
     * 繪製文本
     *
     * @param canvas   畫布
     * @param drawInfo 文本信息
     */
    public static void stringDraw(Graphics2D canvas, Object drawInfo) {
        StringDraw stringDraw = (StringDraw) drawInfo;
        canvas.setColor(stringDraw.getColor());
        canvas.setFont(stringDraw.getFont());
        canvas.drawString(stringDraw.getText(), stringDraw.getX(), stringDraw.getY());
    }


    /**
     * 創建二維碼圖片
     *
     * @param text   二維碼內容
     * @param width  二維碼寬度
     * @param height 二維碼高度
     * @return
     * @throws WriterException
     */
    public static BufferedImage createQrCodeImage(String text, int width, int height) throws WriterException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();

        Map<EncodeHintType, Object> hints = new HashMap<>(3);
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.MARGIN, 0);

        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
        return MatrixToImageWriter.toBufferedImage(bitMatrix);
    }

    public static void main(String[] args) throws IOException, WriterException {
        drawPoster();
    }
}

3、運行main 方法

隨便找幾個圖片扔上去,圖片上傳到OSS,得到圖片

運行時間約1-2秒,具體看海報複雜度而定
在這裏插入圖片描述

4、防止重複創建

創建前判斷文件是否存在,如果存在則直接返回圖片地址給到前端

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章