1. 程式人生 > >java 合成兩張圖片或圖片與二維碼

java 合成兩張圖片或圖片與二維碼

java中偶爾會出現需要將一張小圖片嵌入大圖中或帶二維碼的海報圖片,那麼本文就是奔著這個目的來的,直接上臘肉!

zxing是生成1D和2D條形或二維碼的工具類庫,java圖形庫Graphics2D進行圖片的合成。

依賴:

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

 

程式碼:

/*
     * overlapImage
     * @description:合成二維碼和圖片為檔案
     * @author 李陽
     * @date 2018/12/13
     * @params [bigPath, code]
     * @return void
     */
    public void combineCodeAndPicToFile(String bigPath, BufferedImage code/*String samllPath*/) {
        try {
            BufferedImage big = ImageIO.read(new File(bigPath));
            BufferedImage small = code;
            /*//合成兩個檔案時使用
            BufferedImage small = ImageIO.read(new File(smallPath));*/
            Graphics2D g = big.createGraphics();

            //二維碼或小圖在大圖的左上角座標
            int x = (big.getWidth() - small.getWidth()) / 2;
            // int y = (big.getHeight() - small.getHeight()) / 2;
            int y = (big.getHeight() - small.getHeight() - 100);
            g.drawImage(small, x, y, small.getWidth(), small.getHeight(), null);
            g.dispose();
            //為了保證大圖背景不變色,formatName必須為"png"
            ImageIO.write(big, "png", new File("C:/Users/yiyiweizhu/Desktop/BigSmall.jpg"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /* 
     * combineCodeAndPicToInputstream
     * @description:合成二維碼和圖片為輸出流,可用於下載
     * @author 李陽
     * @date 2018/12/13
     * @params [bigPath, code]
     * @return java.io.InputStream
     */
    public InputStream combineCodeAndPicToInputstream(String bigPath, BufferedImage code) {
        ImageOutputStream imOut = null;
        try {
            BufferedImage big = ImageIO.read(new File(bigPath));
            // BufferedImage small = ImageIO.read(new File(smallPath));
            BufferedImage small = code;
            Graphics2D g = big.createGraphics();

            //二維碼或小圖在大圖的左上角座標
            int x = (big.getWidth() - small.getWidth()) / 2;
            int y = (big.getHeight() - small.getHeight() - 100);   //二維碼距大圖下邊距100
            g.drawImage(small, x, y, small.getWidth(), small.getHeight(), null);
            g.dispose();
            ByteArrayOutputStream bs = new ByteArrayOutputStream();
            imOut = ImageIO.createImageOutputStream(bs);
            //為了保證大圖背景不變色,formatName必須為"png"
            ImageIO.write(big, "png", imOut);
            InputStream is = new ByteArrayInputStream(bs.toByteArray());
            return is;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /* 
     * combineCodeAndPicToBase64 
     * @description:合成二維碼和圖片為Base64,用於直接展示
     * @author 李陽
     * @date 2018/12/14
     * @params [bigPath, code]
     * @return java.lang.String
     */
    public String combineCodeAndPicToBase64(String bigPath, BufferedImage code) {
        ImageOutputStream imOut = null;
        try {
            BufferedImage big = ImageIO.read(new File(bigPath));
            // BufferedImage small = ImageIO.read(new File(smallPath));
            BufferedImage small = code;
            Graphics2D g = big.createGraphics();

            //二維碼或小圖在大圖的左上角座標
            int x = (big.getWidth() - small.getWidth()) / 2;
            int y = (big.getHeight() - small.getHeight() - 100);
            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);
            String base64 = Base64.getEncoder().encodeToString(bytes);
            System.out.println(base64);

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

    /* 
     * createImage 
     * @description:生成二維碼
     * @author 李陽
     * @date 2018/12/13
     * @params [content 二維碼內容, logoImgPath 中間logo, needCompress 是否壓縮]
     * @return java.awt.image.BufferedImage
     */
    private BufferedImage createImage(String content, String logoImgPath, boolean needCompress) throws IOException, WriterException {
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        //200是定義的二維碼或小圖片的大小
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 200, 200, hints);
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //迴圈遍歷每一個畫素點
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        // 沒有logo
        if (logoImgPath == null || "".equals(logoImgPath)) {
            return image;
        }

        // 插入logo
        insertImage(image, logoImgPath, needCompress);
        return image;
    }

    /* 
     * insertImage 
     * @description:二維碼插入logo
     * @author 李陽
     * @date 2018/12/13
     * @params [source, logoImgPath, needCompress]
     * @return void
     */
    private insertImage(BufferedImage source, String logoImgPath, boolean needCompress) throws IOException {
        File file = new File(logoImgPath);
        if (!file.exists()) {
            return;
        }

        Image src = ImageIO.read(new File(logoImgPath));
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        //處理logo
        if (needCompress) {
            if (width > WIDTH) {
                width = WIDTH;
            }

            if (height > HEIGHT) {
                height = HEIGHT;
            }

            Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics gMaker = tag.getGraphics();
            gMaker.drawImage(image, 0, 0, null); // 繪製縮小後的圖
            gMaker.dispose();
            src = image;
        }

        // 在中心位置插入logo
        Graphics2D graph = source.createGraphics();
        int x = (200 - width) / 2;
        int y = (200 - height) / 2;
        graph.drawImage(src, x, y, width, height, null);
        Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }

    public static final void main(String[] args) throws IOException, WriterException {
        // combineCodeAndPicToFile("C:/Users/kevin/Desktop/qqq.jpg", "C:/Users/kevin/Desktop/1111.png");
        BufferedImage code = createImage("http://www.baidu.com", null, false);
        // combineCodeAndPicToFile("C:/Users/kevin/Desktop/a.png", code);
        combineCodeAndPicToBase64("C:/Users/kevin/Desktop/hjj.jpg", code);
    }
}

 

參考:
http://www.zhaochengquan.com/2018/03/29/%E5%9F%BA%E4%BA%8EZXing%E7%9A%84%E4%BA%8C%E7%BB%B4%E7%A0%81%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E4%B8%8E%E5%9B%BE%E7%89%87%E5%90%88%E6%88%90/

https://blog.csdn.net/qq_35971258/article/details/80593500