项目中我们经常会用到二维码,今天就来讲讲二维码的生成:
1, 二维码的概念: 二维条码/二维码(2-dimensional bar code)是用某种特定的集合图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的图形.(二维码的黑点代表二进制的1,空白代表二进制的0); 2, 一维码(条形码) 是由一组粗细不同,黑白(或彩色)相间的条,空及其相应的字符(数字字母)组成的标记,即传统条码. 3, 二维码分类: 二维码也有许多不同的码制,就码制的编码原理而言,通常分为三种类型: (1), 线性堆叠式二维码; 编码原理: 建立在一维条形码基础之上,按需要堆积成两行或多行; (2), 矩阵式二维码; 最常用的类型: 在一个矩形空间通过黑,白像素在矩阵中的不同分布进行编码. 在矩阵相应元素位置上, 用点(方点,圆点或其他形状)的出现表示二进制"1",点的不出现表示二进制的"0"; (3), 邮政码; 最少使用: 邮政码通过不同长度的条进行编码,主要用于邮件编码,如: POSTNET, BPO4-STATE. 4, 二维码的优缺点: 优点: (1), 高密度编码,信息容量大; (2), 编码范围广; (3), 容错能力强; (4), 译码可靠性高; (5), 可引入加密措施; (6), 成本低,易制作,持久耐用; 缺点: (1), 二维码技术成为手机病毒,钓鱼网站传播的新渠道; (2), 信息泄露 5, QR code: 目前流行的三大国际标准: PDF417: 不支持中文; DM: 专利未公开; QR code: 专利公开,支持中文;相比其他二维码,具有识读速度快,数据密度大,占用空间小的优势; QR code 是由日本Denso公司于1994年研制的一种矩阵二维码符号吗,全称是Quick Response Code. 6, Java生成二维码: ZXing Project, QrCode等,这里主要来测试ZXing的用法:package code;import java.awt.image.BufferedImage;import java.io.File;import java.nio.file.FileSystems;import java.nio.file.Path;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.regex.Pattern;import javax.imageio.ImageIO;import javax.servlet.http.HttpServletResponse;import com.google.zxing.BarcodeFormat;import com.google.zxing.BinaryBitmap;import com.google.zxing.EncodeHintType;import com.google.zxing.MultiFormatReader;import com.google.zxing.MultiFormatWriter;import com.google.zxing.Result;import com.google.zxing.client.j2se.BufferedImageLuminanceSource;import com.google.zxing.client.j2se.MatrixToImageWriter;import com.google.zxing.common.BitMatrix;import com.google.zxing.common.HybridBinarizer;import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;/** * Maven 仓库: ** * * Jar包: * javase-3.3.1.jar; * core-3.3.1.jar; * *//** *@description TODO 二维码生成解析类 *@date 2018/1/22 *@author geYang **/public class QrCode { /** * @description TODO 生成QR_Code图片 * @param size 生成图片大小 * @param content 内容 * @param path 生成的地址 * @return String * @date 2018年1月22日下午4:54:28 * @author geYang **/ public static String generateQrCode(Integer size, String content, String path, boolean isQrCode) throws Exception{ String imageName = getNowDate()+".png"; BitMatrix matrix; if(isQrCode){ matrix = generateQrCode(size, content); } else { matrix = generateEna13Code(content); } //生成二维码图片: Path file = FileSystems.getDefault().getPath(path, imageName); MatrixToImageWriter.writeToPath(matrix, "png", file); return path+imageName; } /** * @description TODO 生成图片流 * @author geYang **/ public static void generateQrCode(Integer size, String content, HttpServletResponse response, boolean isQrCode) throws Exception{ BitMatrix matrix; if(isQrCode){ matrix = generateQrCode(size, content); } else { matrix = generateEna13Code(content); } MatrixToImageWriter.writeToStream(matrix, "png", response.getOutputStream()); response.getOutputStream().flush(); response.getOutputStream().close(); } public static BitMatrix generateQrCode(Integer size, String content) throws Exception{ size = (size==null || size<300) ? 300 : size; //定义二维码参数: HashMapcom.google.zxing *javase *3.3.1 *hintType = new HashMap<>(); hintType.put(EncodeHintType.CHARACTER_SET, "utf-8"); //纠错等级 hintType.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); //二维码与图片边距 hintType.put(EncodeHintType.MARGIN, 2); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hintType); return bitMatrix; } /** * 生成一维码(条形码) * @author geYang **/ public static BitMatrix generateEna13Code(String content) throws Exception{ HashMap hintType = new HashMap<>(); hintType.put(EncodeHintType.CHARACTER_SET, "utf-8"); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.EAN_13, 105, 50, hintType); return bitMatrix; } /** * @description TODO 解析二维码/条形码 * @return String * @date 2018年1月22日下午5:08:13 * @author geYang * @throws Exception **/ public static String decoder(String path) throws Exception{ MultiFormatReader formatReader = new MultiFormatReader(); File input = new File(path); BufferedImage read = ImageIO.read(input); BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(read))); Result result = formatReader.decode(binaryBitmap); return result.getText(); } /**当前时间*/ private static String getNowDate(){ SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); return sf.format(new Date()); } /** * 百度百科: https://baike.baidu.com/item/%E6%9D%A1%E5%BD%A2%E7%A0%81/278988?fr=aladdin * @description TODO 生成商品条形码数字内容 * @param 69838 地区代码:69838 代表中国大陆 * @param shopCode 商品代码(5位数字) 代表着生产厂商代码,由厂商申请,国家分配 * @param productCode 商品代码(4位数字) 代表着厂内商品代码,由厂商自行确定 * @return String * @date 2018年1月23日下午2:25:40 * @author geYang **/ public static String getEna13CodeContent(String productCode){ return getEna13CodeContent("69838", productCode); } public static String getEna13CodeContent(String shopCode, String productCode){ Pattern pattern = Pattern.compile("[0-9]*"); StringBuffer code = new StringBuffer("693"); if(shopCode==null || shopCode.trim().length()!=5 || !pattern.matcher(shopCode).matches()){ return null; } if(productCode==null || productCode.trim().length()!=4 || !pattern.matcher(productCode).matches()){ return null; } code.append(shopCode).append(productCode); //奇数位和;偶数位和 int sumA=0, sumB = 0; for(int i=0; i
2, 在 Servlet 中使用:
package code;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet("/code")public class QrCodeServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { QrCode.generateQrCode(300, "http://www.baidu.com", response, true); } catch (Exception e) { e.printStackTrace(); } }}
3, jQuery生成二维码:
<%@ page contentType="text/html; charset=UTF-8" %>生成二维码
Java生成二维码就这么简单,推荐使用jQuery来生成二维码(比较简单);