二维码生成和解析,二维码生成解析
分享于 点击 6498 次 点评:276
二维码生成和解析,二维码生成解析
使用开源的二维码库zxing,需要两个依赖包core和javase,core是必须的
依赖包如下:
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.1</version>
</dependency>
代码如下:
package com.xiangyi.qrcode;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
public class QRCodeUtil {
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
public static void addLogo(BufferedImage qrcodeImg, BufferedImage logoImg) {
int qrcodeImgWidth = qrcodeImg.getWidth();
int suitableWidth = qrcodeImgWidth/5;
qrcodeImg.getGraphics().drawImage(logoImg, (qrcodeImgWidth - suitableWidth) / 2,
(qrcodeImgWidth - suitableWidth) / 2, suitableWidth, suitableWidth, null);
}
/**
* 生成二维码
* @param content 二维码内容
* @param width 图片尺寸
* @param dest 存放的二维码的输出流
* @param logo 是否在二维码中间加logo
* @throws WriterException
* @throws IOException
*/
public static void generate(String content, Integer width, OutputStream dest, BufferedImage logo)
throws WriterException, IOException {
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
// 指定纠错等级
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 指定编码格式
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, width, hints);
BufferedImage qrcode = toBufferedImage(bitMatrix);
if (logo != null) {
addLogo(qrcode, logo);
}
ImageIO.write(qrcode, "jpg", dest);
dest.close();
}
/**
* 解析二维码
* @param qrcode 二维码图片
* @return 二维码内容
* @throws NotFoundException
*/
public static String parse(BufferedImage qrcode) throws NotFoundException {
LuminanceSource source = new BufferedImageLuminanceSource(qrcode);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
// 指定编码格式
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
Result result = new MultiFormatReader().decode(bitmap, hints);
return result.getText();
}
}
二维码的算法里包含纠错的功能,也就是说即使一张图片不是完整的二维码,二维码解析软件也有可能解析出其内容。比如在二维码中间加上logo后,这张二维码的部分数据内容就被logo给遮盖住了,这个二维码在严格意义上来讲就不是完整的二维码了,但是即使二维码图片不完整,解析软件仍然有可能识别出其内容,这就是二维码的纠错功能。
二维码纠错等级如下:
/** L = ~7% correction */
L(0x01),
/** M = ~15% correction */
M(0x00),
/** Q = ~25% correction */
Q(0x03),
/** H = ~30% correction */
H(0x02);
L等级可以修复大约7%的内容,H等级可以修复大约30%的内容。纠错等级越高,算法越复杂,可存储的内容也越少,但可丢失的数据也就越多(用这个例子来说就是中间的logo可以越大)。
上面的代码设置纠错等级为H,中间logo的大小为二维码图片大小的1/5,在这种情况下,二维码还是可以识别出来的,如果中间的logo太大,会导致二维码无法识别。
相关文章
- 暂无相关文章
用户点评