QR Code PDF417 汉信码
QR(日)
PDF417(美)
DM(韩)
汉信码(中)
备注
发明时间
1994年
1992年
1989年
2005年
是否中国国家标准
是
是
否
是
是否国际标准
是
是
是
是
面积
(mm*mm)
最小
21*21
90*9
10*10
有84个版本供自主选择,最小码仅有指甲大小
最大
177*177
853*270
144*144
信息存储量
大
最小
小
大
字节/平方英寸
2953(7%纠错信息)
1106(0.2%纠错信息)
1556(14%纠错信息)
4350
数字
4296
2710
3116
7829
字符
7089
1850
235
4350
汉字
1817
2174
二进制
2953
1556
3262
纠错能力
纠错分级
4级
9
非离散分级
4级
纠错能力越强,可以存储的有效信息越少
最高纠错信息
30%
46.20%
25%
30%
最低纠错信息
7%
0.20%
14%
8%
表示中文
优
差
一般
优
解码速度
快
慢
一般
快
抗畸变、污损能力
较弱
一般
超强
强
识别方向性
全方向性
单方向
单方向
全方向性
识别设备
支持手机、PAD、摄像头
限专用设备
支持手机、PAD、摄像头
限专用设备
目前大部分手机二维码软件仅支持QR码
结论:上述资料中,最重要的一条“目前大部分手机二维码软件仅支持QR码”。所以,码制方式选用QR。
QR二维码是目前最常用二维码
是把字符串编码后通过二维图片的黑白两色模块显示出来
可表示的字符串长度和 容错率(ECC) 显示编码模式(EncodeMode)及版本(Version)有关
容错率共四档:
L 7% M 15% Q 25% H 30% 注:7% --> 7%的字码可被修正。
QR码有容错能力,QR码图形如果有破损,仍然可以被机器读取内容,最高可以到7%~30%面积破损仍可被读取。
编码模式:
Numeric 数字
Alphanumeric 英文字母
Binary 二进制
Kanji 汉字
版本(Version):
1-40 共40个版本
1 21x21模块
40 177x177模块
每增加一个版本每边增加4个模块 ,如: 版本2 为25x25模块
以下几张图片是字符串'www.sohu.com'的二维码使用了不同的版本的效果
版本1
版本3版本7版本10版本40
5、QR码具体java代码。
可以通过以下方法设置容错、编码模式、版本
setQrcodeErrorCorrect L M Q H
setQrcodeEncodeMode N数字 A英文 其他为Binary
setQrcodeVersion 不设置会自动选择适当的版本
这个库只是通过calQrcode方法返回表示二维码的数组,图像需要自己处理
boolean[][] s = testQrcode.calQrcode(d);
通过开源的java 程序生成二维码。
1、SwetakeQRCode 一个日本人写的。
2、google开源 ZXing。
参考链接:http://ylq365.iteye.com/blog/1160635
1)SwetakeQRCode Demo(创建二维码以及解析二维码):
需要的jar包:http://download.csdn.net/detail/wojiao555555/7578417
类:QRCodeSwetakeDemo.java
- package ljk.QRcode.swetake;
- import java.awt.Color;
- import java.awt.Graphics2D;
- import java.awt.geom.AffineTransform;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.IOException;
- import javax.imageio.ImageIO;
- import jp.sourceforge.qrcode.QRCodeDecoder;
- import jp.sourceforge.qrcode.exception.DecodingFailedException;
- import com.swetake.util.Qrcode;
- /**
- * 二维码生成demo 使用 swetake开源工具
- *
- * link:http://blog.csdn.net/wojiao555555/article/details/36184705
- */
- public class QRCodeSwetakeDemo {
- public static void main(String args[]) throws Exception{
- String sms = "http://www.wodsy.com";
- String filePath = "C:\\Users\\Administrator\\Desktop\\QRcode124.png";
- //QR码是正方形的,所以最好宽度和高度值相同
- int width = 500;
- int height = 500;
- createrImage(sms, filePath, width, height);
- String decodeMsg = decoderImage(filePath);
- System.out.println("二维码内容为:"+decodeMsg);
- }
- /**
- * 创建二维码
- *
- * @param sms_info 信息内容 如:www.wodsy.com
- * @param filePath 输出路径 如:"C:\\Users\\Administrator\\Desktop\\QRcode124.png"
- * @param width 宽度 生成二维码的宽度
- * @param height 高度 生成二维码的高度
- * @throws Exception
- */
- public static void createrImage(String sms_info,String filePath,int width,int height) throws Exception {
- try {
- Qrcode testQrcode = new Qrcode();
- testQrcode.setQrcodeErrorCorrect('M');//设置错误容错率 L(7%) M(15%) Q(25%) H(30%)
- testQrcode.setQrcodeEncodeMode('B');//设置编码模式 N数字 A英文 其他为Binary (设置为A的时候生成的二维码异常)
- testQrcode.setQrcodeVersion(7);//设置版本 (1~40)
- 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; // 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();//释放此图形的上下文以及它使用的所有系统资源。调用 dispose 之后,就不能再使用 Graphics 对象。
- bi.flush();
- File f = new File(filePath);
- if (!f.exists()) {
- f.createNewFile();
- }
- // 图像缩放
- bi=resize(bi,width,height);
- // 创建图片
- ImageIO.write(bi, "png", f);
- }else {
- System.out.println("信息编码后长度过长,请升高版本值(比如 testQrcode.setQrcodeVersion(10)),或降低容错率(比如:testQrcode.setQrcodeErrorCorrect(L))");
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 图像缩放
- * @param source
- * @param targetW
- * @param targetH
- * @return
- */
- public 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 imgPath 二维码路径
- * @return 二维码内容
- */
- public static String decoderImage(String imgPath){
- File imageFile = new File(imgPath);
- BufferedImage bufImg = null;
- String content = null;
- try {
- bufImg = ImageIO.read(imageFile);
- QRCodeDecoder decoder = new QRCodeDecoder();
- content = new String(decoder.decode(new TwoDimensionCodeImage(bufImg)), "UTF-8");
- } catch (IOException e) {
- System.out.println("Error: " + e.getMessage());
- e.printStackTrace();
- } catch (DecodingFailedException dfe) {
- System.out.println("Error: " + dfe.getMessage());
- dfe.printStackTrace();
- }
- return content;
- }
- }
类:TwoDimensionCodeImage.java
- package ljk.QRcode.swetake;
- import java.awt.image.BufferedImage;
- import jp.sourceforge.qrcode.data.QRCodeImage;
- public class TwoDimensionCodeImage implements QRCodeImage {
- BufferedImage bufImg;
- public TwoDimensionCodeImage(BufferedImage bufImg) {
- this.bufImg = bufImg;
- }
- @Override
- public int getHeight() {
- return bufImg.getHeight();
- }
- @Override
- public int getPixel(int x, int y) {
- return bufImg.getRGB(x, y);
- }
- @Override
- public int getWidth() {
- return bufImg.getWidth();
- }
- }
生成的二维码:尺寸:500 X 500 像素。
2)ZXingQRCode Demo(创建二维码以及解析二维码):
优点:
qrcode有1-40个version
version愈大,容错越高,像素愈多
qrcode的api把version给屏蔽掉了。
它自己根据输入的文字量和容错级别,
算出来需要多少bit来存数据。
然后循环所有的version,
看哪个能放下这么多字,就用哪个version。
这样的话,优势是生成的qrcode一直最小。一个牛掰的作者生成的二维码链接:http://blog.csdn.net/kimmking/article/details/8244552
参考链接:http://blog.csdn.net/yangdong0906/article/details/8558871
ZXing jar包获取步骤:http://blog.csdn.net/chonbj/article/details/17913577
http://www.cnblogs.com/tankaixiong/archive/2010/10/31/1865807.html
jar包简化:http://www.cnblogs.com/keyindex/archive/2011/06/08/2074900.html
需要的jar包:http://download.csdn.net/detail/wojiao555555/7606799
类:QRCodeZXingDemo.java
- package ljk.QRcode.ZXing.ok;
- import java.awt.Graphics2D;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.IOException;
- import java.util.Hashtable;
- import javax.imageio.ImageIO;
- import ljk.QRcode.ZXing.addImage.MatrixToImageConfigEx;
- import ljk.QRcode.ZXing.addImage.MatrixToImageWriterEx;
- import com.google.zxing.BarcodeFormat;
- import com.google.zxing.EncodeHintType;
- import com.google.zxing.MultiFormatWriter;
- import com.google.zxing.WriterException;
- import com.google.zxing.client.j2se.MatrixToImageWriter;
- import com.google.zxing.common.BitMatrix;
- import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
- /**
- * @Description 二维码demo 包含生成、解析、生成带logo图片的二维码。
- * @version 1.0 2014-07-03
- * @author LJK
- */
- public class QRCodeZXingDemo {
- public QRCodeZXingDemo() {}
- /**
- * @Title: createQRCode
- * @Description: 生成二维码图片
- * @param @param content 二维码文字内容
- * @param @param width 二维码图片宽度
- * @param @param height 二维码图片高度
- * @param @param imageSavePath 二维码图片保存路径
- * @param @param imgFormat 二维码图片格式, jpg/png 等
- * @param @throws IOException
- * @return void
- * @throws
- */
- public void createQRCode(String content, int width, int height, String imageSavePath, String imgFormat) throws IOException{
- Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
- hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
- //指定错误纠正级别 共四个级别:
- /*
- L 7%
- M 15%
- Q 25%
- H 30%
- */
- hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); //互联网应用二维码不会破损,L容错即可,易识别
- BitMatrix matrix = null;
- try {
- //BarcodeFormat.QR_CODE:设置条行码类型
- /*
- 支持如下几种条形码
- public static final BarcodeFormat AZTEC;
- public static final BarcodeFormat CODABAR;
- public static final BarcodeFormat CODE_39;
- public static final BarcodeFormat CODE_93;
- public static final BarcodeFormat CODE_128;
- public static final BarcodeFormat DATA_MATRIX;
- public static final BarcodeFormat EAN_8;
- public static final BarcodeFormat EAN_13;
- public static final BarcodeFormat ITF;
- public static final BarcodeFormat MAXICODE;
- public static final BarcodeFormat PDF_417;
- public static final BarcodeFormat QR_CODE;
- public static final BarcodeFormat RSS_14;
- public static final BarcodeFormat RSS_EXPANDED;
- public static final BarcodeFormat UPC_A;
- public static final BarcodeFormat UPC_E;
- public static final BarcodeFormat UPC_EAN_EXTENSION;
- */
- matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
- writeToFile(matrix, imgFormat, imageSavePath);
- } catch (WriterException e) {
- e.printStackTrace();
- }
- }
- /**
- * @Title: createQrCode
- * @Description: 生成二维码图片,并添加 logo (logo自动缩放为 二维码图片的 1/4大小)【注意】尽量不要使用黑白logo,影响识别。
- * @param @param content 二维码内容
- * @param @param width 二维码宽度
- * @param @param height 二维码高度
- * @param @param imageSavePath 二维码保存路径
- * @param @param imgFormat 二维码图片格式, jpg/png 等
- * @param @param logoPath logo 路径
- * @return void
- * @throws
- */
- public void createQrCode(String content, int width, int height, String imageSavePath, String imgFormat, String logoPath){
- Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
- hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
- hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); //之后要破坏图片添加logo,所以容错率调高(H),防止不能识别。
- BitMatrix matrix = null;
- try {
- matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
- writeToFile(matrix, imgFormat, imageSavePath, logoPath);
- } catch (WriterException e) {
- e.printStackTrace();
- }
- }
- /**
- * @Title: writeToFile
- * @Description: 写出二维码到磁盘,包含logo
- * @param @param matrix 二维码 bit矩阵
- * @param @param imgFormat 二维码图片格式, jpg/png 等
- * @param @param imageSavePath 二维码保存路径
- * @param @param logoPath logo 路径
- * @return void
- * @throws
- */
- public void writeToFile(BitMatrix matrix, String imgFormat,String imageSavePath, String logoPath) {
- try {
- //写出图片
- BufferedImage image = writeToFile(matrix, imgFormat, imageSavePath);
- // //添加logo
- MatrixToImageWriterExtend.overlapImage(image, imageSavePath, logoPath, imgFormat);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * @Title: writeToFile
- * @Description: 写出图片到磁盘
- * @param @param matrix 二维码 bit 矩阵
- * @param @param imgFormat 二维码图片格式,jpg/png 等
- * @param @param imageSavePath 二维码保存路径
- * @param @throws IOException
- * @return BufferedImage 二维码缓存
- * @throws
- */
- public BufferedImage writeToFile(BitMatrix matrix, String imgFormat,
- String imageSavePath) throws IOException {
- File file = new File(imageSavePath);
- BufferedImage image = MatrixToImageWriterExtend.writeToFile(matrix, imgFormat, file);
- return image;
- }
- /**
- * @Title: main
- * @Description: 测试
- * @param @param args
- * @return void
- * @throws
- */
- public static void main(String[] args) {
- String content = "http://www.wodsy.com";
- String imageSavePath = "C:/Users/Administrator/Desktop/testode.png";
- String logoPath = "C:/Users/Administrator/Desktop/logo2.jpg";
- String imgFormat = "png";
- int width = 200;
- int height = 200;
- QRCodeZXingDemo qrCode = new QRCodeZXingDemo();
- try {
- //写出二维码
- // qrCode.createQRCode(content, width, height, imageSavePath, imgFormat);
- //写出带logo 的二维码
- qrCode.createQrCode(content, width, height, imageSavePath, imgFormat, logoPath);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
类:MatrixToImageWriterExtend.java
- package ljk.QRcode.ZXing.ok;
- import java.awt.Graphics2D;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.IOException;
- import java.io.OutputStream;
- import javax.imageio.ImageIO;
- import com.google.zxing.common.BitMatrix;
- /**
- * @ClassName: MatrixToImageWriterExtend
- * @Description: 继承源代码中 MatrixToImageWriter 类,但该类是final的。所以把方法全部取出构建该类。
- * @author LJK
- * @date 2014-7-7 下午12:17:50
- *
- */
- public class MatrixToImageWriterExtend {
- private static final int BLACK = 0xFF000000;
- private static final int WHITE = 0xFFFFFFFF;
- private MatrixToImageWriterExtend() {
- }
- 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;
- }
- /**
- * @Title: writeToFile
- * @Description: ZXing 的源代码,只不过把 BufferedImage 对象返回了。
- * @param @param matrix
- * @param @param format
- * @param @param file
- * @param @return
- * @param @throws IOException
- * @return BufferedImage
- * @throws
- */
- public static BufferedImage writeToFile(BitMatrix matrix, String format, File file)
- throws IOException {
- BufferedImage image = toBufferedImage(matrix);
- if (!ImageIO.write(image, format, file)) {
- throw new IOException("Could not write an image of format "
- + format + " to " + file);
- }
- return image;
- }
- /**
- * @Title: overlapImage
- * @Description: 二维码添加自定义logo(关键部分)
- * @param @param image 二维码缓存
- * @param @param imgSavePath 二维码保存路径
- * @param @param logoPath logo 路径
- * @param @param formate 二维码图片格式,jpg/png 等
- * @return void
- * @throws
- */
- public static void overlapImage(BufferedImage image, String imgSavePath, String logoPath, String formate) {
- try {
- BufferedImage logo = ImageIO.read(new File(logoPath));
- Graphics2D g = image.createGraphics();
- // logo宽高
- double logoWidth = logo.getWidth();
- double logoHeight = logo.getHeight();
- //logo 等比缩放
- while(logoWidth>image.getWidth()/2.5){
- logoWidth /= 1.25;
- logoHeight /= 1.25;
- }
- int width = (int)logoWidth;
- int height = (int)logoHeight;
- // logo起始位置,此目的是为logo居中显示
- int x = (image.getWidth() - width) / 2;
- int y = (image.getHeight() - height) / 2;
- g.drawImage(logo, x, y, width, height, null);
- g.dispose();
- ImageIO.write(image, formate, new File(imgSavePath));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public static void writeToStream(BitMatrix matrix, String format,
- OutputStream stream) throws IOException {
- BufferedImage image = toBufferedImage(matrix);
- if (!ImageIO.write(image, format, stream)) {
- throw new IOException("Could not write an image of format "
- + format);
- }
- }
- }
生成的二维码:
尺寸:500 X 500 像素。
注意:ZXing 生成的二维码是有白边的,并且生成图像哪块代码不用自己写,很方便。
完事了~~
上述demo的地址:http://download.csdn.net/detail/wojiao555555/7606829
联系客服