最近在做商家的模块,需要生成二维码。本来开始想着直接生成二维码就行 ,经过和产品等沟通,需要二维码带上logo等
于是自己写了一个工具类,可以直接使用。有些路径和文件名生成规则需要自己改下,注释已经写的很详细了。希望对大家有所帮助
package com.allk.utils;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
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.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
/**
* @Author Darren
* @Time 2017年9月5日 上午10:57:14
* @Description:二维码生成/解析
*/
public class QRCodeUtils {
/** 图片格式 */
public static final String QRCODE_PNG = "png";
public static final String QRCODE_JPG = "jpg";
public static final String QRCODE_GIF = "gif";
public static final String QRCODE_BMP = "bmp";
public static final String QRCODE_JPEG = "jpeg";
public static final String QRCODE_PNM = "pnm";
private static final Integer QRCode$width = 200;
private static final Integer QRCode$height = 200;
private static final int QRCOLOR = 0xFF000000; // 默认是黑色
private static final int BGWHITE = 0xFFFFFFFF; // 背景颜色
/** 二维码图片存储服务器路径 */
public static final String QRCode$imgSrc = "/images/qrcode";
/** 二维码logo图片,默认使用logo图片 */
public static final String QRCode$logoImg = "/images/public/pinklogo.jpg";
/**
* 不带logo的二维码
*
* @param text 二维码附带的信息
* @param path 要存放二维码图片的路径
* @param format 图片格式 /jpg,png,gif..........
* @param file 需要显示在二维码中心位置的小图标(图片)
* @throws Exception
* @throws WriterException
* @throws IOException
*/
public static final String[] createQRCode(String text, String path, String format)
throws WriterException, IOException {
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, QRCode$width, QRCode$height,
getDecodeHintType());
String filePath = path + QRCode$imgSrc + "/" + createServerImgName();
File outputFile = new File(filePath);
MatrixToImageWriter.writeToFile(bitMatrix, format, outputFile);// 生成不带中心位置图标的二维码图片
String[] img = new String[3];
img[0] = QRCode$imgSrc + "/" + createServerImgName();
img[1] = String.valueOf(QRCode$width);
img[2] = String.valueOf(QRCode$height);
return img;
}
/**
* 带logo的二维码
*
* @param text 二维码附带的信息
* @param path 要存放二维码图片的路径
* @param format 图片格式 /jpg,png,gif..........
* @param file 需要显示在二维码中心位置的小图标(图片)
* @throws Exception
* @throws WriterException
* @throws IOException
*/
public static final String[] createLogoQRCode(String text, String path, String format, File file)
throws WriterException, IOException {
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, QRCode$width, QRCode$height,
getDecodeHintType());
int w = bitMatrix.getWidth();
int h = bitMatrix.getHeight();
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
// 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? QRCOLOR : BGWHITE);
}
}
BufferedImage bufferedImage = null;
if (file != null) {
bufferedImage = encodeImgLogo(image, file);// 绘制二维码自定义中心位置图片,注意实际格式,更改图片后缀名为满足的格式无效
} else {
// logo图片
String logoPath = path + QRCode$logoImg;
bufferedImage = encodeImgLogo(image, new File(logoPath));// 绘制二维码中心位置logo图片
}
if (bufferedImage == null) {
return null;
}
// 重新生成带logo的二维码图片
String imgName = createServerImgName();
String QRClogCode = path + QRCode$imgSrc + "/" + imgName;
ImageIO.write(bufferedImage, format, new File(QRClogCode));// 生成带中心位置图标的二维码图片
String[] img = new String[3];
img[0] = QRCode$imgSrc + "/" + imgName;
img[1] = String.valueOf(QRCode$width);
img[2] = String.valueOf(QRCode$height);
return img;
}
/**
* 解析二维码,需要javase包。 文件方式解码
*
* @param file
* @return
*/
public static String decode(File file) {
BufferedImage image;
try {
if (file == null || file.exists() == false) {
throw new Exception(" File not found:" + file.getPath());
}
image = ImageIO.read(file);
return unifiedDecode(image);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解析二维码 流方式解码
*
* @param input
* @return
*/
public static String decode(InputStream input) {
BufferedImage image;
try {
if (input == null) {
throw new Exception(" input is null");
}
image = ImageIO.read(input);
return unifiedDecode(image);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static String unifiedDecode(BufferedImage image) throws NotFoundException {
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result;
// 解码设置编码方式为:utf-8,
Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
result = new MultiFormatReader().decode(bitmap, hints);
return result.getText();
}
/**
* 生成文件名
* @return
*/
public static final String createServerImgName() {
UUID serverImgUuid = UUID.randomUUID();
return DateFormatterUtils.getDateTime() + serverImgUuid.toString();// 文件名
}
/**
* 设置二维码的格式参数
*
* @return
*/
public static Map<EncodeHintType, Object> getDecodeHintType() {
// 用于设置QR二维码参数
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
// 设置QR二维码的纠错级别(H为最高级别)具体级别信息
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 设置编码方式
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 0);
hints.put(EncodeHintType.MAX_SIZE, 350);
hints.put(EncodeHintType.MIN_SIZE, 100);
return hints;
}
/**
* 二维码绘制logo
*
* @param image
* @param logoImg
* logo图片文件 格式:JPG, jpg, tiff, pcx, PCX, bmp, BMP, gif, GIF,
* WBMP, png, PNG, raw, RAW, JPEG, pnm, PNM, tif, TIF, TIFF,
* wbmp, jpeg
* @throws IOException
*/
public static BufferedImage encodeImgLogo(BufferedImage image, File logoImg) throws IOException {
// String[] names = ImageIO.getReaderFormatNames();
// System.out.println(Arrays.toString(names));
// 能读取的图片格式:JPG, jpg, tiff, pcx, PCX, bmp, BMP, gif, GIF, WBMP, png, PNG, raw, RAW, JPEG, pnm, PNM, tif, TIF, TIFF, wbmp, jpeg
// 读取二维码图片
// 获取画笔
Graphics2D g = image.createGraphics();
// 读取logo图片
BufferedImage logo = ImageIO.read(logoImg);
// 设置二维码大小,太大,会覆盖二维码,此处20%
int logoWidth = logo.getWidth(null) > image.getWidth() * 2 / 10 ? (image.getWidth() * 2 / 10)
: logo.getWidth(null);
int logoHeight = logo.getHeight(null) > image.getHeight() * 2 / 10 ? (image.getHeight() * 2 / 10)
: logo.getHeight(null);
// 设置logo图片放置位置
// 中心
int x = (image.getWidth() - logoWidth) / 2;
int y = (image.getHeight() - logoHeight) / 2;
// 右下角,15为调整值
// int x = twodimensioncode.getWidth() - logoWidth-15;
// int y = twodimensioncode.getHeight() - logoHeight-15;
// 开始合并绘制图片
g.drawImage(logo, x, y, logoWidth, logoHeight, null);
g.drawRoundRect(x, y, logoWidth, logoHeight, 15, 15);
// logo边框大小
g.setStroke(new BasicStroke(2));
// logo边框颜色
g.setColor(Color.WHITE);
g.drawRect(x, y, logoWidth, logoHeight);
g.dispose();
logo.flush();
image.flush();
return image;
}
}
pom.xml
<!-- google ZXing Core工具包,生成二维码 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
二维码
最简单的生成二维码
pom.xml
<!-- 二维码 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
public String xcxSimulationQrcode(String scene) throws Exception {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode("https://open.weixin.qq.com/sns/getexpappinfo?appid=xxxxxxxxx&path=pages/gradEnroll/gradEnroll.html?scene="+scene,
BarcodeFormat.QR_CODE, 600, 600);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, "PNG", outputStream);
Base64.Encoder encoder = Base64.getEncoder();
String text = encoder.encodeToString(outputStream.toByteArray());
return text;
}
返回的是base64不加头的