7 changed files with 278 additions and 1 deletions
@ -0,0 +1,224 @@ |
|||||
|
package com.elink.esua.epdc.commons.tools.utils; |
||||
|
|
||||
|
import com.elink.esua.epdc.commons.tools.constant.StrConstant; |
||||
|
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; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.codec.CharEncoding; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
|
||||
|
import javax.imageio.ImageIO; |
||||
|
import java.awt.*; |
||||
|
import java.awt.geom.RoundRectangle2D; |
||||
|
import java.awt.image.BufferedImage; |
||||
|
import java.io.File; |
||||
|
import java.io.InputStream; |
||||
|
import java.io.OutputStream; |
||||
|
import java.net.URL; |
||||
|
import java.util.Hashtable; |
||||
|
|
||||
|
/** |
||||
|
* 二维码工具类 |
||||
|
* |
||||
|
* @author yujintao |
||||
|
* @date 2018/11/12 14:49 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
public class QrCodeUtils { |
||||
|
|
||||
|
/** |
||||
|
* 二维码尺寸 |
||||
|
*/ |
||||
|
private static final int QRCODE_SIZE = 800; |
||||
|
|
||||
|
/** |
||||
|
* 生成二维码图片,并转为byte[] |
||||
|
* |
||||
|
* @param content 二维码内的信息 |
||||
|
* @param imgPath logo地址 |
||||
|
* @param needCompress 是否压缩logo |
||||
|
* @return java.awt.image.BufferedImage |
||||
|
* @author work@yujt.net.cn |
||||
|
* @date 2020/8/7 10:58 |
||||
|
*/ |
||||
|
public static byte[] encodeByByte(String content, String imgPath, boolean needCompress) { |
||||
|
return FileUtils.imageToBytes(encodeByImage(content, imgPath, needCompress), StrConstant.SUFFIX_IMG_PNG); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成二维码图片 |
||||
|
* |
||||
|
* @param content 二维码内的信息 |
||||
|
* @param imgPath logo地址 |
||||
|
* @param needCompress 是否压缩logo |
||||
|
* @return java.awt.image.BufferedImage |
||||
|
* @author work@yujt.net.cn |
||||
|
* @date 2020/8/7 10:58 |
||||
|
*/ |
||||
|
public static BufferedImage encodeByImage(String content, String imgPath, boolean needCompress) { |
||||
|
BufferedImage image = null; |
||||
|
try { |
||||
|
image = QrCodeUtils.createImage(content, imgPath, needCompress); |
||||
|
} catch (Exception e) { |
||||
|
log.error("创建二维码失败,\n content={} \n imagePath={}", content, imgPath); |
||||
|
} |
||||
|
return image; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 生成二维码(内嵌LOGO),选择是否压缩logo,直接存入指定文件目录 |
||||
|
* |
||||
|
* @param content 内容 |
||||
|
* @param imgPath LOGO地址 |
||||
|
* @param destPath 存放目录 |
||||
|
* @param needCompress 是否压缩LOGO |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception { |
||||
|
BufferedImage image = QrCodeUtils.createImage(content, imgPath, needCompress); |
||||
|
mkdirs(destPath); |
||||
|
ImageIO.write(image, StrConstant.SUFFIX_IMG_PNG, new File(destPath)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成二维码(内嵌LOGO),不压缩logo,直接存入指定目录 |
||||
|
* |
||||
|
* @param content 内容 |
||||
|
* @param imgPath LOGO地址 |
||||
|
* @param destPath 存储地址 |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static void encode(String content, String imgPath, String destPath) throws Exception { |
||||
|
QrCodeUtils.encode(content, imgPath, destPath, false); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成二维码,不插入logo |
||||
|
* |
||||
|
* @param content 内容 |
||||
|
* @param destPath 存储地址 |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static void encode(String content, String destPath) throws Exception { |
||||
|
QrCodeUtils.encode(content, null, destPath, false); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成二维码(内嵌LOGO) |
||||
|
* |
||||
|
* @param content 内容 |
||||
|
* @param imgPath LOGO地址 |
||||
|
* @param output 输出流 |
||||
|
* @param needCompress 是否压缩LOGO |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static void encode(String content, String imgPath, OutputStream output, boolean needCompress) |
||||
|
throws Exception { |
||||
|
BufferedImage image = QrCodeUtils.createImage(content, imgPath, needCompress); |
||||
|
ImageIO.write(image, StrConstant.SUFFIX_IMG_PNG, output); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成二维码 |
||||
|
* |
||||
|
* @param content 内容 |
||||
|
* @param output 输出流 |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static void encode(String content, OutputStream output) throws Exception { |
||||
|
QrCodeUtils.encode(content, null, output, false); |
||||
|
} |
||||
|
|
||||
|
private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception { |
||||
|
Hashtable<EncodeHintType, Object> hints = new Hashtable(); |
||||
|
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); |
||||
|
hints.put(EncodeHintType.CHARACTER_SET, CharEncoding.UTF_8); |
||||
|
hints.put(EncodeHintType.MARGIN, 1); |
||||
|
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, |
||||
|
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); |
||||
|
} |
||||
|
} |
||||
|
if (StringUtils.isBlank(imgPath)) { |
||||
|
return image; |
||||
|
} |
||||
|
// 插入logo图片
|
||||
|
QrCodeUtils.insertImage(image, imgPath, needCompress); |
||||
|
return image; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 插入LOGO |
||||
|
* |
||||
|
* @param source 二维码图片 |
||||
|
* @param imgPath LOGO图片地址 |
||||
|
* @param needCompress 是否压缩 |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception { |
||||
|
|
||||
|
URL url = new URL(imgPath); |
||||
|
InputStream is = url.openConnection().getInputStream(); |
||||
|
|
||||
|
Image src = ImageIO.read(is); |
||||
|
int width = src.getWidth(null); |
||||
|
int height = src.getHeight(null); |
||||
|
// 压缩LOGO
|
||||
|
if (needCompress) { |
||||
|
// 限制最大LOGO宽度
|
||||
|
int maxWidth = QRCODE_SIZE / 4; |
||||
|
// 限制最大LOGO高度
|
||||
|
int maxHeight = QRCODE_SIZE / 4; |
||||
|
|
||||
|
if (width > maxWidth) { |
||||
|
width = maxWidth; |
||||
|
} |
||||
|
if (height > maxHeight) { |
||||
|
height = maxHeight; |
||||
|
} |
||||
|
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_SIZE - width) / 2; |
||||
|
int y = (QRCODE_SIZE - 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(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常) |
||||
|
* |
||||
|
* @param destPath 存放目录 |
||||
|
* @author lanyuan Email: mmm333zzz520@163.com |
||||
|
* @date 2013-12-11 上午10:16:36 |
||||
|
*/ |
||||
|
private static void mkdirs(String destPath) { |
||||
|
File file = new File(destPath); |
||||
|
// 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
|
||||
|
if (!file.exists() && !file.isDirectory()) { |
||||
|
file.mkdirs(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
Loading…
Reference in new issue