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