二维码的原理及生成解析(JAVA)

二维条码/二维码(2D barcode) 是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化等特点。最早起源于日本,原本是Denso Wave公司为了追踪汽车零部件而设计的一种条码

具体生成解析代码如下:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import jp.sourceforge.qrcode.QRCodeDecoder;
import jp.sourceforge.qrcode.data.QRCodeImage;
import jp.sourceforge.qrcode.exception.DecodingFailedException;

import com.swetake.util.Qrcode;

public class QRCodeDecoderUtil
{
 
 /**
     * 生成二维码图片
     * @param content
     * @param imgPath
     */
    public static boolean encoderQRCode(String content, String imgPath)
    {
     Qrcode qrcodeHandler = new Qrcode();

     /**
      * 设置二维码纠错等级
      * L-默认:可以识别已损失的7%的数据
      * M-可以识别已损失15%的数据
      * Q-可以识别已损失25%的数据
      * H-可以识别已损失30%的数据
      * 纠错等级越高可存储的信息越少,但对二维码清晰度的要求越小
      */
        qrcodeHandler.setQrcodeErrorCorrect('M');

       
        qrcodeHandler.setQrcodeEncodeMode('B');

        // 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
        int version = 6;
        qrcodeHandler.setQrcodeVersion(version);
       
        byte[] contentBytes = null;
        try
        {
         contentBytes = content.getBytes("gb2312");
        }
        catch(Exception ex)
        {
         ex.printStackTrace();
         return false;
        }
       
        BufferedImage bufImg = new BufferedImage(140, 140, BufferedImage.TYPE_INT_RGB);

        Graphics2D gs = bufImg.createGraphics();
        gs.setBackground(Color.WHITE);
        gs.clearRect(0, 0, 140, 140);
       
        // 设置图像颜色
        gs.setColor(Color.BLACK);
       
        // 设置偏移量 避免解析出错
        int pixoff = 2;
       
        // 限制最字节数,与version有关
        int limit = 120;
       
        int len = null == contentBytes? 0:contentBytes.length;
        if (len > 0 && len < limit)
        {
            boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);
            for (int i = 0; i < codeOut.length; i++)
            {
                for (int j = 0; j < codeOut.length; j++)
                {
                    if (codeOut[j][i])
                    {
                        gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
                    }
                }
            }
        }
        else
        {
            System.err.println("QRCode content bytes length = "
                    + contentBytes.length + " not in [ 0,"+limit+" ]. ");
            return false;
        }
       
        gs.dispose();
        bufImg.flush();

        File imgFile = new File(imgPath);
//        if (mkDir(imgFile))
//        {
         try
         {
    ImageIO.write(bufImg, "png", imgFile);
   }
         catch (IOException e)
         {
    e.printStackTrace();
    return false;
   }
//        }
        return true;
    }
   
//    private static boolean mkDir(File file)
//    {
//     if(file.getParentFile().exists())
//     {
//      return true;
//     }
//     else
//     {
//      if (mkDir(file.getParentFile()))
//     {
//      return file.mkdir();
//     }
//     else
//     {
//      return false;
//     }
//     }
//   }
   
   
    /**
     *
     * 解析二维码
     * @param imgPath
     *
     */
    public static String decoderQRCode(String imgPath)
    {
     File imageFile = new File(imgPath);
     BufferedImage bufImg = null;

        String decodedData = null;
        try
        {
            bufImg = ImageIO.read(imageFile);
            QRCodeDecoder decoder = new QRCodeDecoder();
            QRImage qrImage = new QRImage(bufImg);
            decodedData = new String(decoder.decode(qrImage));
        }
        catch (IOException e)
        {
            e.printStackTrace();

        }
        catch (DecodingFailedException ex)
        {
            ex.printStackTrace();
        }
        return decodedData;

    }


 /**
  * @param args
  */
 public static void main(String[] args)
 {
  String imgPath = "D:\\qrcode\\TEST.png";
  boolean result = QRCodeDecoderUtil.encoderQRCode("http://www.baidu.com", imgPath);
  
  if (result)
  {
   System.out.println(QRCodeDecoderUtil.decoderQRCode(imgPath));
  }
 }
}

class QRImage implements QRCodeImage
{
 BufferedImage bufImg;

 public QRImage(BufferedImage bufImg)
 {
  this.bufImg= bufImg;
 }

 public int getWidth()
 {
  return bufImg.getWidth();
 }

 public int getHeight()
 {
  return bufImg.getHeight();
 }

 public int getPixel(int x, int y)
 {
  return bufImg.getRGB(x,y);
 }
}

相关推荐