二维码生成和解析

使用开源的二维码库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太大,会导致二维码无法识别。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值