【JAVA】使用ZXing生成巢狀圖片的二維碼
阿新 • • 發佈:2019-01-04
1.先下載zxing開發包,這裡用到的只是core那個jar包
2.使用zxing開發還需要一個類,程式碼如下
package com.sudytech.zxing; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.imageio.ImageIO; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; public class ZXingTest { // 圖片寬度的一般 private static final int IMAGE_WIDTH = 60; private static final int IMAGE_HEIGHT = 60; private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2; private static final int FRAME_WIDTH = 2; // 二維碼寫碼器 private static MultiFormatWriter mutiWriter = new MultiFormatWriter(); public static void main(String[] args) { ZXingTest .encode("weixin://wxpay/bizpayurl?appid=wxf8b4f85f3a794e77&noncestr=pyqHJLTwa2H3Vz3k&productid=abc&sign=6f19c6f90ace86f18c906c9ce2a5288e7ed7fd55×tamp=1432796925", 300, 300, "F:\\zxing\\LeeYefang.jpg", "F:\\zxing\\ewm.jpg"); System.out.println("success"); } /** * * @param content * 二維碼顯示的文字 * @param width * 二維碼的寬度 * @param height * 二維碼的高度 * @param srcImagePath * 中間巢狀的圖片 * @param destImagePath * 二維碼生成的地址 */ public static void encode(String content, int width, int height, String srcImagePath, String destImagePath) { try { // ImageIO.write 引數 1、BufferedImage 2、輸出的格式 3、輸出的檔案 ImageIO.write(genBarcode(content, width, height, srcImagePath), "jpg", new File(destImagePath)); } catch (IOException e) { e.printStackTrace(); } catch (WriterException e) { e.printStackTrace(); } } /** * 得到BufferedImage * * @param content * 二維碼顯示的文字 * @param width * 二維碼的寬度 * @param height * 二維碼的高度 * @param srcImagePath * 中間巢狀的圖片 * @return * @throws WriterException * @throws IOException */ private static BufferedImage genBarcode(String content, int width, int height, String srcImagePath) throws WriterException, IOException { // 讀取源影象 BufferedImage scaleImage = scale(srcImagePath, IMAGE_WIDTH, IMAGE_HEIGHT, true); int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT]; for (int i = 0; i < scaleImage.getWidth(); i++) { for (int j = 0; j < scaleImage.getHeight(); j++) { srcPixels[i][j] = scaleImage.getRGB(i, j); } } Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>(); // 設定編碼格式 hint.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 設定QR二維碼的糾錯級別——這裡選擇最高H級別 hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 生成二維碼,引數順序分別為:編碼內容,編碼型別,生成圖片寬度,生成圖片高度,設定引數 BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hint); // 開始利用二維碼資料建立Bitmap圖片,分別設為黑白兩色 // 二維矩陣轉為一維畫素陣列 int halfW = matrix.getWidth() / 2; int halfH = matrix.getHeight() / 2; int[] pixels = new int[width * height]; for (int y = 0; y < matrix.getHeight(); y++) { for (int x = 0; x < matrix.getWidth(); x++) { // 讀取圖片 if (x > halfW - IMAGE_HALF_WIDTH && x < halfW + IMAGE_HALF_WIDTH && y > halfH - IMAGE_HALF_WIDTH && y < halfH + IMAGE_HALF_WIDTH) { pixels[y * width + x] = srcPixels[x - halfW + IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH]; } // 在圖片四周形成邊框 else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH) || (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH) || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH - IMAGE_HALF_WIDTH + FRAME_WIDTH) || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)) { pixels[y * width + x] = 0xfffffff; } else { // 此處可以修改二維碼的顏色,可以分別制定二維碼和背景的顏色; pixels[y * width + x] = matrix.get(x, y) ? 0xff000000 : 0xfffffff; } } } BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); image.getRaster().setDataElements(0, 0, width, height, pixels); return image; } /** * 把傳入的原始影象按高度和寬度進行縮放,生成符合要求的圖示 * * @param srcImageFile * 原始檔地址 * @param height * 目標高度 * @param width * 目標寬度 * @param hasFiller * 比例不對時是否需要補白:true為補白; false為不補白; * @throws IOException */ private static BufferedImage scale(String srcImageFile, int height, int width, boolean hasFiller) throws IOException { double ratio = 0.0; // 縮放比例 File file = new File(srcImageFile); BufferedImage srcImage = ImageIO.read(file); Image destImage = srcImage.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH); System.out.println(srcImage.getWidth() + " - " + srcImage.getHeight()); // 計算比例 if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) { if (srcImage.getHeight() > height) { ratio = (new Integer(height)).doubleValue() / srcImage.getHeight(); } else { ratio = (new Integer(width)).doubleValue() / srcImage.getWidth(); } AffineTransformOp op = new AffineTransformOp( AffineTransform.getScaleInstance(ratio, ratio), null); destImage = op.filter(srcImage, null); } if (hasFiller) {// 補白 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D graphic = image.createGraphics(); graphic.setColor(Color.white); graphic.fillRect(0, 0, width, height); if (width == destImage.getWidth(null)){ graphic.drawImage(destImage, 0, (height - destImage.getHeight(null)) / 2, destImage.getWidth(null), destImage.getHeight(null), Color.white, null); }else{ graphic.drawImage(destImage, (width - destImage.getWidth(null)) / 2, 0, destImage.getWidth(null), destImage.getHeight(null), Color.white, null); } graphic.dispose(); destImage = image; } return (BufferedImage) destImage; } }