1. 程式人生 > 實用技巧 >java實現圖片和二維碼的合成

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