生成二维码的网站可用于测试:草料二维码
二维码 (2-dimensional bar code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的。
在许多种类的二维条码中,常用的码制有:Data Matrix, Maxi Code, Aztec, QR Code, Vericode, PDF417, Ultracode, Code 49, Code 16K等。
二维条码/二维码可以分为堆叠式/行排式二维条码和矩阵式二维条码。其中矩阵式二维码因QR CODE而广泛流行,我们现在所说的二维码一般即指QR CODE。
QR(Quick-Response) code是被广泛使用的一种二维码,解码速度快。具有以下特点:1.存储大容量信息;2.在小空间内打印;3.有效表现各种字母(1994年由日本DW公司发明);4.对变脏和破损的适应能力强;5.可以从任意方向读取(三处定位图案);6.支持数据合并功能。
QR code包括:QR码(模型1模型2),Micro QR码,iQR码。
QR code的基本结构如下:
二维码基本结构
位置探测图形、位置探测图形分隔符、定位图形:用于对二维码的定位,对每个QR码来说,位置都是固定存在的,只是大小规格会有所差异;
校正图形:规格确定,校正图形的数量和位置也就确定了;
格式信息:表示改二维码的纠错级别,分为L、M、Q、H;
版本信息:即二维码的规格,QR码符号共有40种规格的矩阵(一般为黑白色),从21x21(版本1),到177x177(版本40),每一版本符号比前一版本 每边增加4个模块。
数据和纠错码字:实际保存的二维码信息,和纠错码字(用于修正二维码损坏带来的错误)。
QR码的编码过程:1.数据分析;2.数据编码;;3.纠错编码;4.构造最终数据信息;5.构造矩阵;6.掩摸;7.格式和版本信息。
QR码的解码过程:有兴趣可查阅:如何笔算解码二维码?
以上文本摘抄自参考资料,具体概念请查阅原文。
java生成二维码demo:
本demo基于springboot。
1、添加依赖:
<!-- 二维码相关 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
<!-- 长链接转短链接 相关 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
2、编写工具类:
ShortNetAddressUtil.java:
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/**
*
* 长链接转短链接的工具类<br>
* @author zhu
*
*/
public class ShortNetAddressUtil {
public static CloseableHttpClient httpclient;
static {
httpclient = HttpClients.createDefault();
}
/**
* 生成短连接信息
*/
public static String generateShortUrl(String url) {
try {
HttpPost httpost = new HttpPost("http://suo.im/api.php");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("format", "utf-8")); // 编码
params.add(new BasicNameValuePair("url", url)); // 用户名称
httpost.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
HttpResponse response = httpclient.execute(httpost);
String jsonStr = EntityUtils.toString(response.getEntity(), "utf-8");
return jsonStr;
} catch (Exception e) {
e.printStackTrace();
return "Error";
}
}
/**
* 测试生成短连接
*/
public static void main(String[] args) {
String url = generateShortUrl(
"https://www.baidu.com/s?wd=%E7%A0%81%E4%BA%91&rsv_spt=1&rsv_iqid=0x964c1c3500030761&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=48021271_11_hao_pg&rsv_enter=1&oq=spring%2520data%2520jpa%25E8%2587%25AA%25E5%25AE%259A%25E4%25B9%2589%25E6%2596%25B9%25E6%25B3%2595%25E8%25A7%2584%25E8%258C%2583&rsv_t=d5f86AreI8IAKjbxCKuUMFkUO6EKFeso61joDwkdQQrpLo%2BgDuuyujzyCafz%2B5gC8IMw8TR3iRoe&rsv_pq=f35da7870001b1ba&inputT=7063&rsv_sug3=74&rsv_sug1=50&rsv_sug7=100&bs=spring%20data%20jpa%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B9%E6%B3%95%E8%A7%84%E8%8C%83");
System.out.println(url);
}
}
测试结果:
注意:
这个工具类用来将长链接转换成短链接。在实际项目中,二维码往往都与微信或支付宝挂钩,而与它们挂钩的话链接必然很长,太长的链接会降低二维码的识别速度以及识别率,所以要将它们转换成短链接。常用的缩短网址接口有百度的,新浪的,但是我按照网上的测试百度和新浪的都失败了,所以用了suo.im这个网的接口。这个接口经测试可用,但是偶尔扫码时偶尔会扫出广告。如果知道怎么用百度接口或者新浪接口的老铁还请赐教哦!
QRCodeUtil.java:
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
/**
* 生成二维码图片流
*
* @author zhu
*
*/
public class QRCodeUtil {
public static BitMatrix generateQRCodeStream(String content,HttpServletResponse response) {
//给相应添加头部信息,主要告诉浏览器返回的是图片流
response.setHeader("Cache-Control", "no-store");
// 不设置缓存
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/png");
//设置图片的文字编码以及内边框
Map<EncodeHintType, Object> hints = new HashMap<>();
//编码
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
//边框距
hints.put(EncodeHintType.MARGIN, 0);
BitMatrix bitMatrix;
try {
//参数分别为:编码内容、编码类型、图片宽度、图片高度,设置参数
bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 300, 300,hints);
}catch(WriterException e) {
e.printStackTrace();
return null;
}
return bitMatrix;
}
}
这个工具类的BitMatrix
方法就是将传入的content
生成二维码。
3、编写Controller:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.zhu.QRCodeTest.util.QRCodeUtil;
import com.zhu.QRCodeTest.util.ShortNetAddressUtil;
/**
* 测试生成二维码
*
* @author zhu
*
*/
@Controller
@RequestMapping("/qrcode")
public class QRCodeTestController {
@RequestMapping(value = "/generateqrcode", method = RequestMethod.GET)
@ResponseBody
public void generateQRCode4Product(HttpServletRequest request, HttpServletResponse response) {
String longUrl;
try {
longUrl = "https://www.jianshu.com/u/c0aa31157ba5";
// 转换成短url
String shortUrl = ShortNetAddressUtil.generateShortUrl(longUrl);
// 生成二维码
BitMatrix qRcodeImg = QRCodeUtil.generateQRCodeStream(shortUrl, response);
// 将二维码输出到页面中
MatrixToImageWriter.writeToStream(qRcodeImg, "png", response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:
这个controller首先是先定义了一个longUrl,然后调用工具类转换成短shortUrl,再调用生成二维码的工具类,传入shortUrl,生成二维码,最后用response输出到页面中。
这里并没有用到HttpServletRequest
,删掉也可以。在实际项目开发中,longUrl肯定不是写死的,肯定是根据前端传入的各种参数拼接而成,HttpServletRequest
就是用来获取前端参数的。
测试:
在浏览器直接输入localhost:8080/qrcode/generateqrcoe
,就可看到二维码
手机任意工具扫描二维码就可以进入到刚才controller中写的longUrl。
在页面中显示二维码只需要用img标签,src指向该controller路由即可。如下:
4、前端页面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<img alt="二维码" src="/qrcode/generateqrcode">
</body>
</html>
访问前端页面:
经测试,二维码也是有效的。
总结:
生成二维码其实也挺简单的,说白了就是两个工具类以及一个将二维码输出到客户端的controller。
作者:贪挽懒月
链接:https://www.jianshu.com/p/5f73f2afb1ff
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
推荐一个免barcode api,这个控件有免费版的,生成二维码的代码比较简单