QR二维码是目前最常用二维码
是把字符串编码后通过二维图片的黑白两色模块显示出来
可表示的字符串长度和 容错率(ECC) 显示编码模式(EncodeMode)及版本(Version)有关
容错率共四档:
L 7%
M 15%
Q 25%
H 30%
编码模式:
Numeric 数字
Alphanumeric 英文字母
Binary 二进制
Kanji 汉字
版本(Version):
1-40 共40个版本
1 21x21模块
40 177x177模块
每增加一个版本每边增加4个模块 ,如: 版本2 为25x25模块
以下两张图片是字符串'www.sohu.com'的二维码使用了不同的版本的效果
版本1 版本7
每个版本不同容错率可表示长度可在这里查看http://www.qrcode.com/en/vertable1.html
通过开源Java程序生成二维码
ZXing
- /**
- * @param contents 字符串内容
- * @param width 宽度
- * @param height 高度
- * @param imgPath 图片输出路径
- */
- public void encode(String contents, int width, int height, String imgPath) {
- Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
- // 指定纠错等级
- hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
- // 指定编码格式
- hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
- try {
- BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
- BarcodeFormat.QR_CODE, width, height, hints);
- MatrixToImageWriter
- .writeToFile(bitMatrix, "png", new File(imgPath));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
/** * @param contents 字符串内容 * @param width 宽度 * @param height 高度 * @param imgPath 图片输出路径 */ public void encode(String contents, int width, int height, String imgPath) { Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(); // 指定纠错等级 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); // 指定编码格式 hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); try { BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints); MatrixToImageWriter .writeToFile(bitMatrix, "png", new File(imgPath)); } catch (Exception e) { e.printStackTrace(); } }
我用的ZXing2.0,发现只要指定了字符集,出来的二维码图片就不能被识别,释掉这句就可以识别了,但中文会乱码。
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
- /**
- * @param sms_info 信息内容
- * @param filePath 输出路径
- * @param width 宽度
- * @param height 高度
- * @throws Exception
- */
- public static void createImage(String sms_info,String filePath,int width,int height) throws Exception {
- try {
- Qrcode testQrcode = new Qrcode();
- testQrcode.setQrcodeErrorCorrect('M');
- testQrcode.setQrcodeEncodeMode('B');
- testQrcode.setQrcodeVersion(7);
- String testString = sms_info;
- byte[] d = testString.getBytes("UTF-8");
- System.out.println(d.length);
- // 限制最大字节数为120
- if (d.length > 0 && d.length < 120) {
- boolean[][] s = testQrcode.calQrcode(d);
- BufferedImage bi = new BufferedImage(s.length, s[0].length,
- BufferedImage.TYPE_BYTE_BINARY);
- Graphics2D g = bi.createGraphics();
- g.setBackground(Color.WHITE);
- g.clearRect(0, 0, s.length, s[0].length);
- g.setColor(Color.BLACK);
- int mulriple=1;
- for (int i = 0; i < s.length; i++) {
- for (int j = 0; j < s.length; j++) {
- if (s[j][i]) {
- g.fillRect(j * mulriple, i * mulriple, mulriple, mulriple);
- }
- }
- }
- g.dispose();
- bi.flush();
- File f = new File(filePath);
- if (!f.exists()) {
- f.createNewFile();
- }
- bi=resize(bi,width,height);
- // 创建图片
- ImageIO.write(bi, "png", f);
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 图像缩放
- * @param source
- * @param targetW
- * @param targetH
- * @return
- */
- private static BufferedImage resize(BufferedImage source, int targetW,
- int targetH) {
- int type = source.getType();
- BufferedImage target = null;
- double sx = (double) targetW / source.getWidth();
- double sy = (double) targetH / source.getHeight();
- target = new BufferedImage(targetW, targetH, type);
- Graphics2D g = target.createGraphics();
- g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
- g.dispose();
- return target;
- }
/** * @param sms_info 信息内容 * @param filePath 输出路径 * @param width 宽度 * @param height 高度 * @throws Exception */ public static void createImage(String sms_info,String filePath,int width,int height) throws Exception { try { Qrcode testQrcode = new Qrcode(); testQrcode.setQrcodeErrorCorrect('M'); testQrcode.setQrcodeEncodeMode('B'); testQrcode.setQrcodeVersion(7); String testString = sms_info; byte[] d = testString.getBytes("UTF-8"); System.out.println(d.length); // 限制最大字节数为120 if (d.length > 0 && d.length < 120) { boolean[][] s = testQrcode.calQrcode(d); BufferedImage bi = new BufferedImage(s.length, s[0].length, BufferedImage.TYPE_BYTE_BINARY); Graphics2D g = bi.createGraphics(); g.setBackground(Color.WHITE); g.clearRect(0, 0, s.length, s[0].length); g.setColor(Color.BLACK); int mulriple=1; for (int i = 0; i < s.length; i++) { for (int j = 0; j < s.length; j++) { if (s[j][i]) { g.fillRect(j * mulriple, i * mulriple, mulriple, mulriple); } } } g.dispose(); bi.flush(); File f = new File(filePath); if (!f.exists()) { f.createNewFile(); } bi=resize(bi,width,height); // 创建图片 ImageIO.write(bi, "png", f); } } catch (Exception e) { e.printStackTrace(); } } /** * 图像缩放 * @param source * @param targetW * @param targetH * @return */ private static BufferedImage resize(BufferedImage source, int targetW, int targetH) { int type = source.getType(); BufferedImage target = null; double sx = (double) targetW / source.getWidth(); double sy = (double) targetH / source.getHeight(); target = new BufferedImage(targetW, targetH, type); Graphics2D g = target.createGraphics(); g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy)); g.dispose(); return target; }
可以通过以下方法设置容错、编码模式、版本
setQrcodeErrorCorrect L M Q H
setQrcodeEncodeMode N数字 A英文 其他为Binary
setQrcodeVersion 不设置会自动选择适当的版本
这个库只是通过calQrcode方法返回表示二维码的数组,图像需要自己处理
boolean[][] s = testQrcode.calQrcode(d);