二维码的原理及生成解析(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);
}
}