二维码概念
二维条码/二维码(2-dimensional bar code)使用某种特定的几何图形按一定规律在平面(二维码方向上)分布的黑白相间的图形记录数据符号信息的图形。
二维码发展历史
- 一维条码是由一组粗细不同、黑白(或彩色)相间的条、空及其相应的字符(字母或数字)组成的标记,即传统条码。
- 二维条码是用某种特定的几何图形按一定规律在平面(二维方向)上分布的条、空相间的图形来记录数据符号信息。
二维码分类
二维码分类有许多不同的码制,就码制的编码原理而言,通常分为三中类型:
1. 线性堆叠式二维码
2. 矩阵式二维码
3. 邮政码
线性堆叠式二维码
编码原理:
建立在一维条码基础之上,按需要堆积成两行或多行。
矩阵式二维码
在矩阵相应元素位置上,用点(方点、圆点或其他图形)的出现表示二进制”1”,点的不出现表示二进制的”0”。
邮政码
邮政码通过不同长度的条进行编码,主要用于邮政编码,如:POSTNET、BPO 4-STATE。
二维码优缺点
优点
- 高密度编码,信息容量大
- 编码范围广
- 容错能力强
- 译码可靠性强
- 可引入加密措施
- 成本低,易制作,持久耐用
缺点
- 二维码技术成为手机病毒、钓鱼网站传播的新渠道
- 信息泄露
QRCode
目前流行的三大国际标准
PDF417:不支持中文
DM:专利未公开,需支付专利费用
QR code:专利公开,支持中文
QR code比其他二维码相比,具有识读速度快、数据密度大、占用空间小的优势
QRCode是由日本Denso公司与1994年研制的一种矩阵二维码符号码,全称是Quick Response Code。
Jsp生成二维码方法
- 借助第三方jar,如zxing和qrcodejar
- Javascript,如jquery.qrcode.js
1. ZXing
1.引入jar包
zxing3.2.1.jar
2.CreateQRcode
package com.imooc.zxing;
import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.io.File;
import java.nio.file.Path;
import java.util.HashMap;
/**
* 生成二维码
* Created by Administrator on 2017/8/14.
*/
public class CreateQRcode {
public static void main(String[] args) {
// 二维码的宽高
int width = 300;
int height = 300;
// 二维码内容
String content = "我是中国人";
// 二维码图片的格式
String format = "png";
// 定义二维码参数
HashMap hints = new HashMap();
// 字符编码
hints.put(EncodeHintType.CHARACTER_SET,"utf-8");
// 纠错等级
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
// 边距
hints.put(EncodeHintType.MARGIN,2);
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,width,height,hints);
// 二维码输出的路径
Path file = new File("D:/code/img.png").toPath();
// 将二维码进行输出
MatrixToImageWriter.writeToPath(bitMatrix,format,file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.ReadQRcode
package com.imooc.zxing;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
/**
* Created by Administrator on 2017/8/14.
*/
public class ReadQRcode {
public static void main(String[] args) {
MultiFormatReader formatReader = new MultiFormatReader();
File file = new File("D:/code/jqueryqrcodeChinese.png");
BufferedImage image = null;
try {
image = ImageIO.read(file);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image)));
// 定义二维码的参数
HashMap hints = new HashMap();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
Result result = formatReader.decode(binaryBitmap, hints);
System.out.println("解析结果: " + result.toString());
System.out.println("二维码格式类型:" + result.getBarcodeFormat());
System.out.println("二维码文本内容:" + result.getText());
} catch (IOException e) {
e.printStackTrace();
} catch (NotFoundException e) {
e.printStackTrace();
}
}
}
具体的代码请查看https://git.oschina.net/liuzhenqing/QRCode.git
2. QRCode
生成:http://www.swetake.com/qrcode/index-e.html
读取:http://osdn.jp/projects/qrcode/
1.CreateQRCode
package com.imooc.qrcode;
import com.swetake.util.Qrcode;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* Created by Administrator on 2017/8/14.
*/
public class CreateQRCode {
public static void main(String[] args) throws Exception {
// 使用QRCode进行绘制二维码
Qrcode x = new Qrcode();
x.setQrcodeErrorCorrect('M');// 纠错等级
x.setQrcodeEncodeMode('B');// N代表数字,A代表a-Z,B代表其他字符
x.setQrcodeVersion(7);// 版本
int width = 67 + 12 * (7 - 1);// 计算宽高有一个公式 67 + 12 * (版本号 - 1)
int heigh = 67 + 12 * (7 - 1);
//String qrData = "我是中国人!";
String qrData = "http://www.baidu.com";
BufferedImage bufferedImage = new BufferedImage(width, heigh, BufferedImage.TYPE_INT_RGB);
Graphics2D gs = bufferedImage.createGraphics();
gs.setBackground(Color.WHITE);
gs.setColor(Color.BLACK);
gs.clearRect(0, 0, width, heigh);
int pixoff = 2;//偏移量
//byte[] d = qrData.getBytes("gb2312");// 中文加上转码
byte[] d = qrData.getBytes();
if (d.length > 0 && d.length < 120) {
boolean[][] s = x.calQrcode(d);
for (int i = 0; i < s.length; i++) {
for (int j = 0; j < s.length; j++) {
if (s[j][i]) {
gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
}
}
}
}
gs.dispose();
bufferedImage.flush();
ImageIO.write(bufferedImage,"png",new File("D:/code/qrcodeLink.png"));
}
}
2.ReadQRCode
package com.imooc.qrcode;
import jp.sourceforge.qrcode.QRCodeDecoder;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
/**
* 读取二维码文件
* Created by Administrator on 2017/8/14.
*/
public class ReadQRCode {
public static void main(String[] args) throws Exception {
File file= new File("D:/code/qrcode.png");
BufferedImage bufferedImage = ImageIO.read(file);
QRCodeDecoder codeDecoder = new QRCodeDecoder();
String result = new String(codeDecoder.decode(new MyQRCodeImage(bufferedImage)),"gb2312");
System.out.println(result);
}
}
3.MyQRCodeImage
package com.imooc.qrcode;
import jp.sourceforge.qrcode.data.QRCodeImage;
import java.awt.image.BufferedImage;
/**
* Created by Administrator on 2017/8/14.
*/
public class MyQRCodeImage implements QRCodeImage {
BufferedImage bufferedImage;
public MyQRCodeImage(BufferedImage bufferedImage) {
this.bufferedImage = bufferedImage;
}
@Override
public int getWidth() {
return bufferedImage.getWidth();
}
@Override
public int getHeight() {
return bufferedImage.getHeight();
}
@Override
public int getPixel(int i, int i1) {
return bufferedImage.getRGB(i, i1);
}
}
具体的代码请查看https://git.oschina.net/liuzhenqing/QRCode.git
2. jquery-qrcode
http://github.com/jeromeetienne/jquery-qrcode
1.引入js文件
jquery.min.js
jquery.qrcode.min.js
2.写界面中生成二维码的代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>生成二维码</title>
<script type="application/javascript" src="<%=request.getContextPath() %>/js/jquery.min.js"></script>
<script type="application/javascript" src="<%=request.getContextPath() %>/js/jquery.qrcode.min.js"></script>
</head>
<body>
<h2>生成的二维码如下:</h2>
<div id="qrcode"></div>
<script type="text/javascript">
/*解决中文*/
function utf16to8(str) {
var out, i, len, c;
out = "";
len = str.length;
for (i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}
$(function () {
jQuery('#qrcode').qrcode(utf16to8("我是中国人!"));
})
</script>
</body>
</html>
具体的代码请查看https://git.oschina.net/liuzhenqing/QRCode.git
实例讲解
为什么都是固定的样式
二维码还可以这样!
如何实现二维码安装手机软件?
以慕课网为例:
苹果:http://itunes.apple.com/cn/app/mu-ke-wang/id722179140?mt=8
安卓:http://www.imooc.com/mobile/appdown
http://www.imooc.com/mobile/mukewang.apk 这种链接不行么?
答案:可以,但是微信不可以,因为只用腾讯自己域名下的apk才可以通过扫一扫下载。
为什么我们的二维码出来是文本而不是链接?
如何实现二维码扫名名片?
VCard是标准通信薄基本格式。
https://zh.wikipedia.org/wiki/VCard