JAVA二維碼編碼&解碼
阿新 • • 發佈:2019-01-06
package web; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Hashtable; import java.util.Map; import javax.imageio.ImageIO; import com.google.zxing.BarcodeFormat; import com.google.zxing.BinaryBitmap; import com.google.zxing.DecodeHintType; import com.google.zxing.EncodeHintType; import com.google.zxing.LuminanceSource; import com.google.zxing.MultiFormatReader; import com.google.zxing.MultiFormatWriter; import com.google.zxing.ReaderException; import com.google.zxing.Result; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; /** * 二維碼編碼&解碼 * @Author: ChenGuiYong 2015年7月13日 上午11:09:56 * @Version: $Id$ * @Desc: <p></p> */ public class QRCodeUtil { private static final int BLACK = 0xFF000000; private static final int WHITE = 0xFFFFFFFF; /* * 解碼: * 1 將圖片反解碼為二維矩陣 * 2 將該二維矩陣解碼為內容 * */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static void decode(String imgPath) { try { File file = new File(imgPath);//獲取該圖片檔案 BufferedImage image; try { image = ImageIO.read(file); if (image == null) { System.out.println("Could not decode image"); } LuminanceSource source = new BufferedImageLuminanceSource(image); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result; Hashtable hints = new Hashtable();//將圖片反解碼為二維矩陣 hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); result = new MultiFormatReader().decode(bitmap, hints);//將該二維矩陣解碼成內容 String resultStr = result.getText(); System.out.println("解碼結果:"+resultStr); } catch (IOException ioe) { System.out.println(ioe.toString()); } catch (ReaderException re) { System.out.println(re.toString()); } } catch (Exception ex) { ex.printStackTrace(); } } /** * 編碼 * @author ChenGuiYong * @data 2015年7月13日 上午11:06:20 * @param contents * @param width * @param height * @param imgPath * @param logoPath * @return */ public static boolean encode(String contents, int width, int height, String imgPath,String logoPath) { Map<EncodeHintType, Object> hints = new Hashtable<>(); // 指定糾錯等級 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 指定編碼格式 hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); //設定二維碼內容到邊框的距離 hints.put(EncodeHintType.MARGIN, 1); String format = "png"; try { BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints); MatrixToImageWriter.writeToStream(bitMatrix, format ,new FileOutputStream(imgPath)); File qrcodeFile = new File(imgPath); //增加logo writeToLogo(bitMatrix,format , qrcodeFile, logoPath); } catch (Exception e) { return false; } System.out.println("編碼成功!"); return true; } /** * 增加Logo * @author ChenGuiYong * @data 2015年7月13日 上午11:07:00 * @param matrix * @param format * @param file * @param logoPath * @throws IOException */ public static void writeToLogo(BitMatrix matrix,String format,File file,String logoPath) throws IOException { Graphics2D graphics2 = null; BufferedImage image = null; BufferedImage logo = null; try { /** * 讀取二維碼圖片,並構建繪圖物件 */ image = toBufferedImage(matrix); graphics2 = image.createGraphics(); /** * 讀取Logo圖片 */ logo = ImageIO.read(new File(logoPath)); int codeWidth = image.getWidth(); int codeHeight = image.getHeight(); /** * 設定logo的大小,設定為二維碼圖片的25%,因為過大會蓋掉二維碼 */ int widthLogo = logo.getWidth(null)>codeWidth*2/13?(codeWidth*2/13):logo.getWidth(null), heightLogo = logo.getHeight(null)>codeHeight*2/13?(codeHeight*2/13):logo.getWidth(null); /** * 計算圖片放置位置 * logo放在中心 */ int x = (codeWidth - widthLogo) / 2; int y = (codeHeight - heightLogo) / 2; int radius = 14;//圓角範圍 //填充與logo大小類似的扁平化圓角矩形背景 graphics2.setComposite(AlphaComposite.Src); graphics2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics2.setColor(Color.WHITE); graphics2.fill(new RoundRectangle2D.Float(x-2, y-2, widthLogo+4, heightLogo+4,radius,radius)); graphics2.setComposite(AlphaComposite.SrcAtop); //開始繪製logo圖片 graphics2.drawImage(logo, x, y, widthLogo, heightLogo, null); if(!ImageIO.write(image, format, file)){ throw new IOException("Could not write an image of format " + format + " to " + file); } } catch (Exception e) { throw e; }finally{ if(graphics2!=null){ graphics2.dispose(); } if(logo!=null){ logo.flush(); } if(image!=null){ image.flush(); } } } public static BufferedImage toBufferedImage(BitMatrix matrix){ int width = matrix.getWidth(); int height = matrix.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, matrix.get(x, y) ? BLACK : WHITE); } } return image; } public static void main(String[] args) { String contents="http://www.baidu.com"; String imgPath = "D:/zxing/zxing.png"; String logoPath = "D:/logo.png"; QRCodeUtil.encode(contents, 200, 200, imgPath,logoPath); QRCodeUtil.decode(imgPath); } }