package com.shinedata.util;
import com.google.zxing.*;
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.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.shinedata.util.wxcard.WxConstant;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.*;
/**
* 二维码生成工具
*
* @Filename QrCodeUtil.java
* @Description
* @Version 1.0
* @Author lixun
* @History <li>Author: lixun</li>
* <li>Date: 2017年3月3日</li>
* <li>Version: 1.0</li>
* <li>Content: create</li>
*/
public class QrCodeUtil {
private static final String CHARSET = "utf-8";
private static final String FORMAT = "PNG";
// 二维码尺寸
private static final int QRCODE_SIZE = 300;
// LOGO高度
private static final int CENTER_IMAGE_HEIGHT = 60;
// LOGO宽度
private static final int CENTER_IMAGE_WIDTH = 60;
public static final String IMG_BASE64_PREFIX = "data:image/png;base64,";
private static Integer j = 2000;
public static String randomNumber() {
String str = System.currentTimeMillis() + "";
str = str.substring(5, 13);
int a = (int) new Random().nextInt(8);
str = Integer.parseInt(str) / (a + 1) + "";
if (str.length() < 8) {
str = str + (int) new Random().nextInt(10);
}
if (j > 3000)
j = 1000;
String data = j + str;
j++;
return data;
}
/**
* 生成二维码 base64
*
* @param content
* @return
* @throws Exception
*/
public static String genBase64Qrcode(String content) throws Exception {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(content,
BarcodeFormat.QR_CODE, 600, 600);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, FORMAT, outputStream);
Base64.Encoder encoder = Base64.getEncoder();
String text = encoder.encodeToString(outputStream.toByteArray());
return text;
}
/**
* 生成二维码(内嵌LOGO)
* 调用者指定二维码文件名
*
* @param content 内容
* @param logoUrl LOGO地址
* @param needCompress 是否压缩LOGO
* @throws Exception
*/
public static QrCode encode(String content, String logoUrl, boolean needCompress) throws Exception {
QrCode qrCode = new QrCode();
qrCode.setContent(content)
.setCenterImageUrl(logoUrl)
.setNeedCompress(needCompress);
return encode(qrCode);
}
public static QrCode encode(QrCode qrCode) throws Exception {
if (qrCode == null) {
throw new IllegalArgumentException("二维码参数异常,qrCode为空");
}
qrCode.checkDefaultProperties();
BufferedImage image = createImage(qrCode);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(image, qrCode.getFormat(), stream);
String base64 = Base64.getEncoder().encodeToString(stream.toByteArray());
qrCode.setBase64QrCode(IMG_BASE64_PREFIX + base64);
return qrCode;
}
/**
* 生成二维码(内嵌LOGO)
*
* @param content 内容
* @param logoUrl LOGO地址
* @param output 输出流
* @param needCompress 是否压缩LOGO
* @throws Exception
*/
public static void encode(String content, String logoUrl, OutputStream output, boolean needCompress)
throws Exception {
QrCode qrCode = new QrCode();
qrCode.setContent(content)
.setCenterImageUrl(logoUrl)
.setNeedCompress(needCompress);
BufferedImage image = createImage(qrCode);
ImageIO.write(image, FORMAT, output);
}
private static BufferedImage createImage(QrCode qrCode) throws Exception {
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix bitMatrix = new MultiFormatWriter().encode(qrCode.getContent(), BarcodeFormat.QR_CODE,
qrCode.getWidth(), qrCode.getHeight(),
hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.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, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
image.setRGB(x, y, bitMatrix.get(x, y) ? qrCode.getColor().getRGB() : qrCode.getBackground().getRGB());
}
}
if (qrCode.getCenterImageUrl() == null || "".equals(qrCode.getCenterImageUrl())) {
return image;
}
// 插入图片
insertImage(image, qrCode);
return image;
}
/**
* 插入LOGO
*
* @param source 二维码图片
* @throws Exception
*/
private static void insertImage(BufferedImage source, QrCode qrCode) throws Exception {
Image src = ImageIO.read(new URL(qrCode.getCenterImageUrl()));
int width = src.getWidth(null);
int height = src.getHeight(null);
if (qrCode.getNeedCompress()) { // 压缩LOGO
if (width > qrCode.getCenterImageWidth()) {
width = qrCode.getCenterImageWidth();
}
if (height > qrCode.getCenterImageHeight()) {
height = qrCode.getCenterImageHeight();
}
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;
}
// 插入LOGO
Graphics2D graph = source.createGraphics();
int x = (qrCode.getWidth() - width) / 2;
int y = (qrCode.getWidth() - height) / 2;
graph.drawImage(src, x, y, width, height, null);
Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
graph.setStroke(new BasicStroke(3f));
graph.draw(shape);
graph.dispose();
}
/**
* 解析二维码
*
* @param path 二维码本地图片地址
* @throws Exception
*/
public static String decodeLocalFile(String path) throws Exception {
BufferedImage image;
image = ImageIO.read(new File(path));
if (image == null) {
return null;
}
return decode(image);
}
/**
* 解析二维码
*
* @param url 二维码网络图片地址
* @throws Exception
*/
public static String decodeUrlFile(String url) throws Exception {
BufferedImage image;
image = ImageIO.read(new URL(url));
if (image == null) {
return null;
}
return decode(image);
}
/**
* 解析二维码
*/
public static String decode(BufferedImage image) throws Exception {
BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
com.google.zxing.Result result;
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
result = new MultiFormatReader().decode(bitmap, hints);
String resultStr = result.getText();
return resultStr;
}
@Data
@Accessors(chain = true)
public static class QrCode {
//二维码内容
private String content;
//二维码logo或者其他图片网络地址,放在二维码中心位置
private String centerImageUrl;
//是否压缩imageUrl
private Boolean needCompress;
//二维码宽
private Integer width;
//二维码高
private Integer height;
//二维码背景色 也可以是new Color()自定义rgb;
private Color background;
//二维码前景色
private Color color;
//中心位置图片宽度
private Integer centerImageWidth;
//中心位置图片高度
private Integer centerImageHeight;
private String format = "PNG";
private String charset = "utf-8";
private String base64QrCode;
public QrCode() {
}
public QrCode(String content, String centerImageUrl, boolean needCompress, Integer width, Integer height,
Color background, Color color, Integer centerImageWidth, Integer centerImageHeight,
String format) {
this.content = content;
this.centerImageUrl = centerImageUrl;
this.needCompress = needCompress;
this.width = width;
this.height = height;
this.background = background;
this.color = color;
this.centerImageWidth = centerImageWidth;
this.centerImageHeight = centerImageHeight;
this.format = format;
this.charset = "utf-8";
}
public void checkDefaultProperties() {
if (this.needCompress == null) {
this.needCompress = false;
}
if (this.width == null) {
this.width = QrCodeUtil.QRCODE_SIZE;
}
if (this.height == null) {
this.height = QrCodeUtil.QRCODE_SIZE;
}
if (this.background == null) {
this.background = Color.WHITE;
}
if (this.color == null) {
this.color = Color.BLACK;
}
if (this.centerImageWidth == null) {
this.centerImageWidth = QrCodeUtil.CENTER_IMAGE_HEIGHT;
}
if (this.centerImageHeight == null) {
this.centerImageHeight = QrCodeUtil.CENTER_IMAGE_WIDTH;
}
}
}
public static void main(String[] args) throws Exception {
String text = "https://preparent.artstep.cn/wechat/payIndex" +
".html?schoolId=1585535185663002&confirmationPersonId=1089&payChannelType=null&profiles=dev";
String logo = "https://shinedata-edu.oss-cn-shanghai.aliyuncs.com/image/e232bca163174e9092afdf116297bc52.jpg";
QrCode qrCode = new QrCode();
qrCode.setContent(text)
.setCenterImageUrl(logo)
.setNeedCompress(true)
.setBackground(Color.WHITE)
.setColor(Color.blue);
System.out.println(encode(qrCode).getBase64QrCode());
}
}
创建二维码并支持自定义logo和颜色
最新推荐文章于 2024-07-30 15:00:49 发布