java 合成兩張圖片或圖片與二維碼
阿新 • • 發佈:2018-12-14
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