java工具类之二维码生成工具类

工具类:

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 * 二维码生成工具类
 * 
 * @author zql
 *
 */
public class QrCodeEncodeUtil {
 
	/**
	 * 创建有logo的二维码图像缓存对象
	 * 
	 * @param content 二维码内容
	 * @param qrCodeSize 二维码图片大小
	 * @param logoFile logo文件对象
	 * @param logoSize logo在二维码中的大小
	 * @return
	 * @throws Exception
	 */
	private static BufferedImage createImage(String content, int qrCodeSize, File logoFile, int logoSize) throws Exception {
		// 二维码图片大小不能小于logo图片大小的3倍,否则生成二维码会出现异常,导致二维码无效
		if (qrCodeSize < logoSize * 3) {
			logoSize = qrCodeSize / 3;
		}
		Hashtable<EncodeHintType, Object> ht = new Hashtable<EncodeHintType, Object>();
		ht.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		ht.put(EncodeHintType.CHARACTER_SET, "UTF-8");
		// 二维码的边界,0为无边界
		ht.put(EncodeHintType.MARGIN, 0);
		// UTF-8编码长度不能超过1273个字节,全是数字字符的话不超过3057
		// 因汉字占了3个字节,所以最多能有424个汉字
		BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, ht);
		BufferedImage image = new BufferedImage(qrCodeSize, qrCodeSize, BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < qrCodeSize; x++) {
			// 如果想要的二维码不是正方形,这里的qrCodeSize请使用二维码图像的高度
			for (int y = 0; y < qrCodeSize; y++) {
				image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
			}
		}
		// 插入logo
		QrCodeEncodeUtil.insertImage(image, logoFile, logoSize);
		return image;
	}
 
	/**
	 * 往二维码图片插入logo
	 * 
	 * @param source 二维码图像缓存对象
	 * @param file logo的文件对象
	 * @param logoSize logo的尺寸
	 * @throws Exception
	 */
	private static void insertImage(BufferedImage source, File file, int logoSize) throws Exception {
		Image src = ImageIO.read(file);
		int width = src.getWidth(null);
		int height = src.getHeight(null);
		// 对logo图片进行压缩
		width = width > logoSize ? logoSize : width;
		height = height > logoSize ? logoSize : height;
		Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
		BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics g = tag.getGraphics();
		// 绘制缩小后的图
		g.drawImage(image, 0, 0, null);
		g.dispose();
		src = image;
		// 因为得到的二维码是正方形,因此只需要获取宽度或高度即可
		int qrCodeSize = source.getWidth();
		// 中间插入LOGO
		Graphics2D graph = source.createGraphics();
		int x = (qrCodeSize - logoSize) / 2;
		int y = (qrCodeSize - logoSize) / 2;
		graph.drawImage(src, x, y, logoSize, logoSize, null);
		/*
		 * @param x 新构造的圆矩形的x坐标 
		 * @param y 新构造的圆矩形的y坐标 
		 * @param w 新构造的圆矩形的宽度
		 * @param h 新构造的圆矩形的高度
		 * @param arcw 圆弧的宽度,用来四舍五入新建的圆矩形的角
		 * @param arch 圆弧的高度,用来四舍五入新建的圆矩形的角
		 * java.awt.geom.RoundRectangle2D.Float.Float(float x, float y, float w, float h, float arcw, float arch)
		 */
		// 外边画个圆距形,让logo不显得那么生硬
		Shape shape = new RoundRectangle2D.Float(x, y, logoSize, logoSize, logoSize / 10, logoSize / 10);
		graph.setStroke(new BasicStroke(3f));
		graph.draw(shape);
		graph.dispose();
	}
	
	/**
	 * 创建二维码图像缓存对象
	 * 
	 * @param content 二维码内容
	 * @param qrCodeSize 二维码图片大小
	 * @return
	 * @throws Exception
	 */
	private static BufferedImage createImage(String content, int qrCodeSize) throws Exception {
		Hashtable<EncodeHintType, Object> ht = new Hashtable<EncodeHintType, Object>();
		ht.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		ht.put(EncodeHintType.CHARACTER_SET, "UTF-8");
		ht.put(EncodeHintType.MARGIN, 0);
		// UTF-8编码长度不能超过1273个字节,全是数字字符的话不超过3057
		// 因汉字占了3个字节,所以最多能有424个汉字
		BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, ht);
		BufferedImage image = new BufferedImage(qrCodeSize, qrCodeSize, BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < qrCodeSize; x++) {
			for (int y = 0; y < qrCodeSize; y++) {
				image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
			}
		}
		return image;
	}
	
	/**
	 * 保存二维码图片自动创建不存在的文件夹
	 * 
	 * @param savePath
	 */
	private static void mkdirs(String savePath) {
		File file = new File(savePath);
		// 当文件夹不存在时,自动创建多层目录
		if (!file.exists() && !file.isDirectory()) {
			// mkdirs和mkdir的区别在于mkdir如果父目录不存在则会抛出异常
			file.mkdirs();
		}
	}
 
	/**
	 * 生成二维码图片
	 * 
	 * @param content 二维码内容
	 * @param logoPath logo路径
	 * @param savePath 二维码保存路径
	 * @param qrCodeSize 二维码图片大小
	 * @param logoSize 二维码图片中的logo大小
	 * @throws Exception
	 */
	public static void encode(String content, String logoPath, String savePath, int qrCodeSize, int logoSize) throws Exception {
		BufferedImage image;
		if (logoPath != null) {
			File logoFile = new File(logoPath);
			if (logoFile.exists()) {
				image = QrCodeEncodeUtil.createImage(content, qrCodeSize, logoFile, logoSize);
			} else {
				image = QrCodeEncodeUtil.createImage(content, qrCodeSize);
			}
		} else {
			image = QrCodeEncodeUtil.createImage(content, qrCodeSize);
		}
		mkdirs(savePath);
		ImageIO.write(image, "JPG", new File(savePath));
	}
 
	/**
	 * 生成二维码图像缓存对象
	 * 
	 * @param content 二维码内容
	 * @param logoPath logo路径
	 * @param qrCodeSize 二维码图片大小
	 * @param logoSize 二维码图片中的logo大小
	 * @return
	 * @throws Exception
	 */
	public static BufferedImage encode(String content, String logoPath, int qrCodeSize, int logoSize) throws Exception {
		BufferedImage image;
		if (logoPath != null) {
			File logoFile = new File(logoPath);
			if (logoFile.exists()) {
				image = QrCodeEncodeUtil.createImage(content, qrCodeSize, logoFile, logoSize);
			} else {
				image = QrCodeEncodeUtil.createImage(content, qrCodeSize);
			}
		} else {
			image = QrCodeEncodeUtil.createImage(content, qrCodeSize);
		}
		return image;
	}
	
	/**
	 * 生成二维码图片
	 * 
	 * @param content 二维码内容
	 * @param savePath 二维码保存路径
	 * @param qrCodeSize 二维码图片大小
	 * @throws Exception
	 */
	public static void encode(String content, String savePath, int qrCodeSize) throws Exception {
		QrCodeEncodeUtil.encode(content, null, savePath, qrCodeSize, 0);
	}
 
	/**
	 * 生成二维码图像缓存对象
	 * 
	 * @param content 二维码内容
	 * @param qrCodeSize 二维码图片大小
	 * @return
	 * @throws Exception
	 */
	public static BufferedImage encode(String content, int qrCodeSize) throws Exception {
		return QrCodeEncodeUtil.encode(content, null, qrCodeSize, 0);
	}
}



测试类:

public class QrCodeEncodeUtilTest {
	
	public static void main(String[] args) throws Exception {
		// 存放在二维码中的内容
		String text = "我是二维码";
		// 嵌入二维码的logo图片路径
		String logoPath = "D:\\image\\logo.jpg";
		// 保存的二维码的路径及名称
		String savePath = "D:\\image\\test.jpg";
		String savePath2 = "D:\\image\\test2.jpg";
		// 生成有logo的二维码
		QrCodeEncodeUtil.encode(text, logoPath, savePath, 400, 300);
		// 生成二维码
		QrCodeEncodeUtil.encode(text, savePath2,300);
 
	}
}

普通项目需要引入的包
core-3.4.0.jar

maven项目依赖

<!-- 二维码 -->
<!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
<dependency>
	<groupId>com.google.zxing</groupId>
	<artifactId>core</artifactId>
	<version>3.4.0</version>
</dependency>
发布了55 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/mr_zql/article/details/100163808