生成二维码的网站可用于测试:草料二维码
参考资料:二维码(QR code)基本结构及生成原理
二维码 (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)@ResponseBodypublic void generateQRCode4Product(HttpServletRequest request, HttpServletResponse response) {String longUrl;try {longUrl = "https://www.jianshu.com/u/c0aa31157ba5";// 转换成短urlString 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,这个控件有免费版的,生成二维码的代码比较简单