java实现二维码的生成和解析:QRCode、zxing 两种方式
第一种:QRCode.jar,使用QRCode生成和解析二维码
1.导入jar包
2.代码
(1)QRCodeUtil .java
1 import com.swetake.util.Qrcode; 2 import jp.sourceforge.qrcode.QRCodeDecoder; 3 4 import javax.imageio.ImageIO; 5 import java.awt.*; 6 import java.awt.image.BufferedImage; 7 import java.io.File; 8 9 public class QRCodeUtil { 10 /** 11 *加密: 文字信息 ->二维码.png 12 * @param content 文字信息 13 * @param imgPath 二维码路径 14 * @param imgType 二维码类型:png 15 * @param size 二维码尺寸 16 * @throws Exception 17 */ 18 public void encoderQRCode(String content,String imgPath,String imgType,int size) throws Exception{ 19 //BufferedImage :内存中的一张图片 20 BufferedImage bufImg = qRcodeCommon(content,imgType,size); 21 22 File file = new File(imgPath);// "src/二维码.png" --> 二维码.png 23 24 //生成图片 25 ImageIO.write(bufImg, imgType, file); 26 } 27 28 /** 29 *产生一个二维码的BufferedImage 30 * @param content 二维码隐藏信息 31 * @param imgType 图片格式 32 * @param size 图片大小 33 * @return 34 */ 35 private BufferedImage qRcodeCommon(String content, String imgType, int size) throws Exception { 36 BufferedImage bufImg =null; 37 //Qrcode对象:字符串->boolean[][] 38 Qrcode qrCodeHandler = new Qrcode(); 39 //设置二维码的排错率:7% L<M<Q<H30% :排错率越高,可存储的信息越少;但是对二维码清晰对要求越小 40 qrCodeHandler.setQrcodeErrorCorrect('M'); 41 //可存放的信息类型:N:数字、 A:数字+A-Z B:所有 42 qrCodeHandler.setQrcodeEncodeMode('B'); 43 //尺寸:取值范围:1-40 44 qrCodeHandler.setQrcodeVersion(size); 45 46 //"Hello world" -> byte[]"Hello world" -->boolean[][] 47 byte[] contentBytes = content.getBytes("UTF-8"); 48 boolean[][] codeOut = qrCodeHandler.calQrcode(contentBytes); 49 50 int imgSize = 67 + 12*(size -1) ; 51 52 //BufferedImage:内存中的图片 53 bufImg = new BufferedImage(imgSize,imgSize,BufferedImage.TYPE_INT_RGB );//red green blue 54 55 //创建一个画板 56 Graphics2D gs = bufImg.createGraphics(); 57 gs.setBackground(Color.WHITE);//将画板的背景色设置为白色 58 gs.clearRect( 0,0, imgSize,imgSize); //初始化 59 gs.setColor(Color.BLACK);//设置 画板上 图像的颜色(二维码的颜色) 60 61 int pixoff = 2 ; 62 63 for(int j=0;j<codeOut.length;j++) { 64 for(int i=0;i<codeOut.length;i++) { 65 if(codeOut[j][i]) { 66 gs.fillRect(j*3+pixoff , i*3+pixoff, 3, 3); 67 } 68 } 69 } 70 //增加LOGO 71 //将硬盘中的src/logo.png 加载为一个Image对象 72 Image logo = ImageIO.read(new File("/src/logo.png") ) ; 73 int maxHeight = bufImg.getHeight(); 74 int maxWdith = bufImg.getWidth(); 75 76 //在已生成的二维码上 画logo 77 gs.drawImage(logo,imgSize/5*2,imgSize/5*2, maxWdith/5,maxHeight/5 ,null) ; 78 79 gs.dispose(); //释放空间 80 bufImg.flush(); //清理 81 return bufImg ; 82 } 83 84 //解密: 二维码(图片路径) -> 文字信息 85 public String decoderQRCode(String imgPath) throws Exception{ 86 87 //BufferedImage内存中的图片 :硬盘中的imgPath图片 ->内存BufferedImage 88 BufferedImage bufImg = ImageIO.read( new File(imgPath) ) ; 89 //解密 90 QRCodeDecoder decoder = new QRCodeDecoder() ; 91 92 TwoDimensionCodeImage tdcImage = new TwoDimensionCodeImage(bufImg); 93 byte[] bs = decoder.decode(tdcImage) ; //bufImg 94 //byte[] -->String 95 String content = new String(bs,"UTF-8"); 96 return content; 97 } 98 99 100 }
(2)TwoDimensionCodeImage .java
1 import jp.sourceforge.qrcode.data.QRCodeImage; 2 3 import java.awt.image.BufferedImage; 4 5 public class TwoDimensionCodeImage implements QRCodeImage { 6 BufferedImage bufImg; //将图片加载到内存中 7 public TwoDimensionCodeImage(BufferedImage bufImg) { 8 this.bufImg = bufImg; 9 } 10 public int getWidth() { 11 return bufImg.getWidth(); 12 } 13 14 public int getHeight() { 15 return bufImg.getHeight(); 16 } 17 18 public int getPixel(int x, int y) { 19 return bufImg.getRGB(x,y); 20 } 21 }
(3)Test .java
1 public class Test { 2 public static void main(String[] args) throws Exception{ 3 //生成二维码 4 /* 5 * 生成图片的路径 src/二维码.png 6 * 文字信息、网址信息 : "helloworld" 7 */ 8 String imgPath = "e:\\二维码2.png"; 9 String content = "http://baidu.com"; //扫描二维码后,网页跳转 10 11 //生成二维码 12 /* 13 * 加密: 文字信息 ->二维码 14 * 解密: 二维码 -> 文字信息 15 */ 16 QRCodeUtil qrUtil = new QRCodeUtil(); 17 //加密: 文字信息 ->二维码 18 qrUtil.encoderQRCode(content, imgPath, "png", 17); 19 20 // TwoDimensionCode handler = new TwoDimensionCode(); 21 // handler.encoderQRCode(content, imgPath, "png", 7); 22 23 24 // //解密: 二维码 -> 文字信息 25 String imgContent = qrUtil.decoderQRCode(imgPath) ; 26 System.out.println(imgContent); 27 28 29 } 30 }
第二种:借助Google提供的ZXing Core工具包
1.maven依赖
1 <dependency> 2 <groupId>com.google.zxing</groupId> 3 <artifactId>core</artifactId> 4 <version>3.4.0</version> 5 </dependency> 6 <dependency> 7 <groupId>com.google.zxing</groupId> 8 <artifactId>javase</artifactId> 9 <version>3.3.1</version> 10 </dependency>
2.代码
(1)ZXingUtil .java
1 import com.google.zxing.*; 2 import com.google.zxing.client.j2se.BufferedImageLuminanceSource; 3 import com.google.zxing.common.BitMatrix; 4 import com.google.zxing.common.HybridBinarizer; 5 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 6 import jp.sourceforge.qrcode.util.Color; 7 8 import javax.imageio.ImageIO; 9 import java.awt.image.BufferedImage; 10 import java.io.File; 11 import java.util.HashMap; 12 import java.util.Hashtable; 13 import java.util.Map; 14 15 public class ZXingUtil { 16 public static void encodeImg(String imgPath,String format,String content,int width,int height,String logo) throws Exception { 17 Hashtable<EncodeHintType,Object > hints = new Hashtable<EncodeHintType,Object>() ; 18 //排错率 L<M<Q<H 19 hints.put( EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H) ; 20 //编码 21 hints.put( EncodeHintType.CHARACTER_SET, "utf-8") ; 22 //外边距:margin 23 hints.put( EncodeHintType.MARGIN, 1) ; 24 /* 25 * content : 需要加密的 文字 26 * BarcodeFormat.QR_CODE:要解析的类型(二维码) 27 * hints:加密涉及的一些参数:编码、排错率 28 */ 29 BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,width,height, hints); 30 //内存中的一张图片:此时需要的图片 是二维码-> 需要一个boolean[][] ->BitMatrix 31 BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); 32 33 for(int x=0;x<width;x++) { 34 for(int y=0;y<height;y++) { 35 image.setRGB(x, y, (bitMatrix.get(x,y)? Color.BLACK:Color.WHITE) ); 36 } 37 } 38 //画logo 39 image = LogoUtil.logoMatrix(image, logo) ; 40 //string->file 41 File file = new File(imgPath); 42 //生成图片 43 ImageIO.write(image, format, file); 44 } 45 46 //解密:二维码->文字 47 public static void decodeImg(File file) throws Exception { 48 if(!file.exists()) return ; 49 //file->内存中的一张图片 50 BufferedImage imge = ImageIO.read(file) ; 51 52 MultiFormatReader formatReader = new MultiFormatReader() ; 53 LuminanceSource source = new BufferedImageLuminanceSource(imge); 54 Binarizer binarizer = new HybridBinarizer(source); 55 BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer); 56 //图片 ->result 57 Map map = new HashMap(); 58 map.put(EncodeHintType.CHARACTER_SET, "utf-8") ; 59 Result result = formatReader.decode(binaryBitmap ,map ) ; 60 System.out.println("解析结果:"+ result.toString()); 61 } 62 63 }
(2)LogoUtil .java
1 import javax.imageio.ImageIO; 2 import java.awt.*; 3 import java.awt.geom.RoundRectangle2D; 4 import java.awt.image.BufferedImage; 5 import java.io.File; 6 import java.io.IOException; 7 8 public class LogoUtil { 9 //传入logo、二维码 ->带logo的二维码 10 public static BufferedImage logoMatrix( BufferedImage matrixImage,String logo ) throws IOException { 11 //在二维码上画logo:产生一个 二维码画板 12 Graphics2D g2 = matrixImage.createGraphics(); 13 14 //画logo: String->BufferedImage(内存) 15 BufferedImage logoImg = ImageIO.read(new File(logo)); 16 int height = matrixImage.getHeight(); 17 int width = matrixImage.getWidth(); 18 //纯logo图片 19 g2.drawImage(logoImg, width * 2 / 5, height * 2 / 5, width * 1 / 5, height * 1 / 5, null); 20 21 //产生一个 画 白色圆角正方形的 画笔 22 BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 23 //将画板-画笔 关联 24 g2.setStroke(stroke); 25 //创建一个正方形 26 RoundRectangle2D.Float round = new RoundRectangle2D.Float(width * 2 / 5, height * 2 / 5, width * 1 / 5, height * 1 / 5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 27 g2.setColor(Color.WHITE); 28 g2.draw(round); 29 30 //灰色边框 31 BasicStroke stroke2 = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 32 g2.setStroke(stroke2); 33 //创建一个正方形 34 RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(width * 2 / 5 + 2, height * 2 / 5 + 2, width * 1 / 5 - 4, height * 1 / 5 - 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); 35 // Color color = new Color(128,128,128) ; 36 g2.setColor(Color.GRAY); 37 g2.draw(round2); 38 39 g2.dispose(); 40 matrixImage.flush(); 41 42 return matrixImage; 43 } 44 }
(3)test.java
1 import java.io.File; 2 3 public class test { 4 public static void main(String[] args) throws Exception { 5 String imgPath = "src/二维码12.png"; 6 String content = "helloworld你好"; 7 String logo = "src/logo.png"; 8 //加密:文字信息->二维码 9 ZXingUtil.encodeImg(imgPath, "png",content, 430, 430,logo); 10 //解密:二维码 ->文字信息 11 ZXingUtil.decodeImg(new File(imgPath)); 12 } 13 }
(效果图)