java實現圖片和二維碼的合成


實現結果

 

實現步驟

1.導入谷歌合成二維碼和圖片的jar包

 
        
<!-- 配置二維碼生成的框架 -->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.1.0</version>
</dependency>
 
        

2.實現二維碼和圖片的生成代碼,響應前台圖片顯示參考轉換base64格式顯示否則亂碼無法展示

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Author 蕭何
 * @Date 2020/8/16 17:47
 */
public class ImgUtil {
    /**
     * 定義二維碼圖片的寬度
     */
    private static final int WIDTH = 125;
    /**
     * 定義二維碼圖片的高度
     */
    private static final int HEIGHT = 125;

    /**
     * 定義LOGO圖片的寬度
     */
    private static final int LOGO_WIDTH = 40;
    /**
     * 定義LOGO圖片的高度
     */
    private static final int LOGO_HEIGHT = 40;


    /**
     * 生成二維碼的方法
     */
    public static BufferedImage execute() throws Exception {
        /** 判斷二維碼中URL */
        String url =null;
        if (url == null || "".equals(url)) {
            url = "禮好啊奧里給!";
        }

        /** 定義Map集合封裝二維碼配置信息 */
        Map<EncodeHintType, Object> hints = new HashMap<>();
        /** 設置二維碼圖片的內容編碼 */
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        /** 設置二維碼圖片的上、下、左、右間隙 */
        hints.put(EncodeHintType.MARGIN, 1);
        /** 設置二維碼的糾錯級別 */
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        /**
         * 創建二維碼字節轉換對象
         * 第一個參數:二維碼圖片中的內容
         * 第二個參數:二維碼格式器
         * 第三個參數:生成二維碼圖片的寬度
         * 第四個參數:生成二維碼圖片的高度
         * 第五個參數:生成二維碼需要配置信息
         *  */
        BitMatrix matrix = new MultiFormatWriter().encode(url,
                BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);

        /** 獲取二維碼圖片真正的寬度  */
        int matrix_width = matrix.getWidth();
        /** 獲取二維碼圖片真正的高度  */
        int matrix_height = matrix.getHeight();
        /** 定義一張空白的緩沖流圖片 */
        BufferedImage image = new BufferedImage(matrix_width, matrix_height,
                BufferedImage.TYPE_INT_RGB);
        /** 把二維碼字節轉換對象 轉化 到緩沖流圖片上 */
        for (int x = 0; x < matrix_width; x++) {
            for (int y = 0; y < matrix_height; y++) {
                /** 通過x、y坐標獲取一點的顏色 true: 黑色  false: 白色 */
                int rgb = matrix.get(x, y) ? 0x000000 : 0xFFFFFF;
                image.setRGB(x, y, rgb);
            }
        }

        /** 獲取公司logo圖片 */
        BufferedImage logo = ImageIO.read(new ClassPathResource("static/img/123.jpg").getInputStream());
        /** 獲取緩沖流圖片的畫筆 */
        Graphics2D g = (Graphics2D) image.getGraphics();
        /** 在二維碼圖片中間繪制公司logo */
        g.drawImage(logo, (matrix_width - LOGO_WIDTH) / 2,
                (matrix_height - LOGO_HEIGHT) / 2, LOGO_WIDTH, LOGO_HEIGHT, null);

        /** 設置畫筆的顏色 */
        g.setColor(Color.WHITE);
        /** 設置畫筆的粗細 */
        g.setStroke(new BasicStroke(5.0f));
        /** 設置消除鋸齒 */
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        /** 繪制圓角矩形 */
        g.drawRoundRect((matrix_width - LOGO_WIDTH) / 2, (matrix_height - LOGO_HEIGHT) / 2,
                LOGO_WIDTH, LOGO_HEIGHT, 10, 10);
        return image;
    }

    // 二維碼和圖片的合成
    public static final void combineCodeAndPicToFile() {
        long starttime = System.currentTimeMillis();
        System.out.println("開始合成:" + starttime);
        try {
            //背景圖
            //BufferedImage big = ImageIO.read(new File(backPicPath));
            BufferedImage big = ImageIO.read(new ClassPathResource("static/img/456.jpg").getInputStream());
            //二維碼的圖片
            //url掃二維碼顯示的內容
            BufferedImage small = execute();
            Graphics2D g = big.createGraphics();  //合成的圖片

            //二維碼或小圖在大圖的左上角坐標
            int x = big.getWidth() - small.getWidth()-45; //加是向右,減是向左
            int y = (big.getHeight() - small.getHeight()-50); //加是向下,減是向上
            //將二維碼花在背景圖上
            g.drawImage(small, x, y, small.getWidth(), small.getHeight(), null);
            //結束繪畫
            g.dispose();
            //為了保證大圖背景不變色,formatName必須為"png"
            ImageIO.write(big, "png", new FileOutputStream("111.jpg"));
            System.out.println("結束合成:" + (System.currentTimeMillis() - starttime) / 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //合成base64響應前台圖片數據展示
    public static final String combineCodeAndPicToBase64(MultipartFile file, HttpServletResponse response) {
        ImageOutputStream imOut = null;
        try {
            BufferedImage big = ImageIO.read(file.getInputStream());
            // BufferedImage small = ImageIO.read(new File(fillPicPath));
            BufferedImage small = ImgUtil.execute();
            Graphics2D g = big.createGraphics();

            //左下角位置
           /* int x = big.getWidth() - small.getWidth()-45; //加是向右,減是向左
            int y = (big.getHeight() - small.getHeight()-50); //加是向下,減是向上*/

            //右下角位置
           /* int x = 45; //加是向右,減是向左
            int y = (big.getHeight() - small.getHeight()-50); //加是向下,減是向上*/
            //居中位置
            int x = (big.getWidth() - small.getWidth())/2; //加是向右,減是向左
            int y = (big.getHeight() - small.getHeight()-50); //加是向下,減是向上

            g.drawImage(small, x, y, small.getWidth(), small.getHeight(), null);
            g.dispose();
            //為了保證大圖背景不變色,formatName必須為"png"
            //字節數組流
            ByteArrayOutputStream bs = new ByteArrayOutputStream();
            //將圖片流轉換為字節數組流
            imOut = ImageIO.createImageOutputStream(bs);
            //將合成好的背景圖輸入到字節數組流中
            ImageIO.write(big, "png", imOut);
            //將字節數組流轉換為二進制流
            InputStream in = new ByteArrayInputStream(bs.toByteArray());

            byte[] bytes = new byte[in.available()];
            //讀取數組流中的數據
            in.read(bytes);
            //轉換為base64數據類型
            String base64 = Base64.getEncoder().encodeToString(bytes);
            System.out.println(base64);

            return "data:image/jpeg;base64," + base64;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        combineCodeAndPicToFile();
    }
}

 

3.更多的合成方式查看此鏈接https://my.oschina.net/kevin2kelly/blog/2988459

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM