JAVA基础--QR_Code二维码生成

项目中我们经常会用到二维码,今天就来讲讲二维码的生成:
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 仓库: 
 *  <dependency>
 *      <groupId>com.google.zxing</groupId>
 *      <artifactId>javase</artifactId>
 *      <version>3.3.1</version>
 *  </dependency>
 *  
 *  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;
        //定义二维码参数:
        HashMap<EncodeHintType, Object> 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<EncodeHintType, Object> 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<code.length(); i++){
            int j = Integer.parseInt(code.substring(i, i+1));
            if((i+1)%2==1){
                sumA = sumA + j;
            } else {
                sumB = sumB + j;
            }
        }
        code.append((10-((sumA+(sumB*3))%10))%10);
        return code.toString();
    }
    
    
    /**
     * 测试
     * */
    public static void main(String[] args) throws Exception {
        String content = getEna13CodeContent("0003");
        System.out.println("生成的条形码内容:"+content);
        String codeImage = generateQrCode(300, content, "C:/Users/yvdedu.com/Desktop/IMGS/code/", false);
        System.out.println("解析的条形码内容:"+decoder(codeImage));
    }
    
}
 

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" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>生成二维码</title>

<!-- 二维码生成工具 -->
<script type="text/javascript" src="<%=request.getContextPath()%>/js/jquery.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/jquery.qrcode.min.js"></script>

</head>
<body>
    <!-- 生成二维码方法: -->
	<div id="qrcode"></div>
	<script type="text/javascript">
		jQuery("#qrcode").qrcode("Hellow jQuery QR_Code")
	</script>

</body>
</html>

Java生成二维码就这么简单,推荐使用jQuery来生成二维码(比较简单);

猜你喜欢

转载自my.oschina.net/u/3681868/blog/1611533