|
|
@@ -27,7 +27,10 @@ import java.awt.image.BufferedImage;
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
import java.io.File;
|
|
|
import java.io.OutputStream;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Collections;
|
|
|
import java.util.Hashtable;
|
|
|
+import java.util.List;
|
|
|
import javax.imageio.ImageIO;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import sun.font.FontDesignMetrics;
|
|
|
@@ -37,21 +40,22 @@ import sun.misc.BASE64Encoder;
|
|
|
* @author ZhaoMn
|
|
|
*/
|
|
|
@Slf4j
|
|
|
-public class QRCodeUtilEx {
|
|
|
+public class QrCodeUtil {
|
|
|
|
|
|
private static final String CHARSET = "utf-8";
|
|
|
private static final String FORMAT_NAME = "JPG";
|
|
|
- // 二维码尺寸
|
|
|
+ /** 二维码尺寸 */
|
|
|
private static final int QRCODE_SIZE = 300;
|
|
|
- // LOGO宽度
|
|
|
+ /** LOGO宽度 */
|
|
|
private static final int WIDTH = 60;
|
|
|
- // LOGO高度
|
|
|
+ /** LOGO高度 */
|
|
|
private static final int HEIGHT = 60;
|
|
|
- // 字体大小
|
|
|
+ /** 字体大小 */
|
|
|
private static final int FONT_SIZE = 18;
|
|
|
+ /** 字体高度 */
|
|
|
+ private static final int FONT_HEIGHT = 30;
|
|
|
|
|
|
-
|
|
|
- private static BufferedImage createImage(String content, String bottomDes, String imgPath,
|
|
|
+ private static BufferedImage createImage(String content, List<String> bottomDes, String imgPath,
|
|
|
boolean needCompress) throws Exception {
|
|
|
Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
|
|
|
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
|
|
|
@@ -62,9 +66,9 @@ public class QRCodeUtilEx {
|
|
|
int width = bitMatrix.getWidth();
|
|
|
int height = bitMatrix.getHeight();
|
|
|
int tempHeight = height;
|
|
|
- boolean needDescription = (null != bottomDes && !"".equals(bottomDes));
|
|
|
+ boolean needDescription = (null != bottomDes && bottomDes.size() > 0);
|
|
|
if (needDescription) {
|
|
|
- tempHeight += 30;
|
|
|
+ tempHeight += (FONT_HEIGHT * bottomDes.size());
|
|
|
}
|
|
|
BufferedImage image = new BufferedImage(width, tempHeight, BufferedImage.TYPE_INT_RGB);
|
|
|
for (int x = 0; x < width; x++) {
|
|
|
@@ -74,52 +78,74 @@ public class QRCodeUtilEx {
|
|
|
}
|
|
|
// 插入图片
|
|
|
if (imgPath != null && !"".equals(imgPath)) {
|
|
|
- QRCodeUtilEx.insertImage(image, imgPath, needCompress);
|
|
|
+ insertImage(image, imgPath, needCompress);
|
|
|
}
|
|
|
//添加底部文字
|
|
|
if (needDescription) {
|
|
|
- QRCodeUtilEx.addFontImage(image, bottomDes);
|
|
|
+ addFontImage(image, bottomDes);
|
|
|
}
|
|
|
return image;
|
|
|
}
|
|
|
|
|
|
+ private static BufferedImage createImage(String content, String bottomDes, String imgPath,
|
|
|
+ boolean needCompress) throws Exception {
|
|
|
+ return createImage(content, Collections.singletonList(bottomDes), imgPath, needCompress);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 添加 底部图片文字
|
|
|
*
|
|
|
* @param source 图片源
|
|
|
* @param declareText 文字本文
|
|
|
*/
|
|
|
- private static void addFontImage(BufferedImage source, String declareText) {
|
|
|
- BufferedImage textImage = strToImage(declareText, QRCODE_SIZE, 50);
|
|
|
+ private static void addFontImage(BufferedImage source, List<String> declareText) {
|
|
|
+
|
|
|
Graphics2D graph = source.createGraphics();
|
|
|
//开启文字抗锯齿
|
|
|
graph.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
|
|
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
|
|
|
|
|
- int width = textImage.getWidth(null);
|
|
|
- int height = textImage.getHeight(null);
|
|
|
+ for(int i = 0; i < declareText.size(); i ++){
|
|
|
+ String declare = declareText.get(i);
|
|
|
+ BufferedImage textImage = strToImage(declare);
|
|
|
+ int width = textImage.getWidth(null);
|
|
|
+ int height = textImage.getHeight(null);
|
|
|
+ int y = QRCODE_SIZE + (declareText.size() * 20) - ((declareText.size() - i - 1) * FONT_HEIGHT);
|
|
|
+ graph.drawImage(textImage, 0, y, width, height, null);
|
|
|
+ }
|
|
|
|
|
|
- graph.drawImage(textImage, 0, QRCODE_SIZE - 20, width, height, null);
|
|
|
graph.dispose();
|
|
|
}
|
|
|
|
|
|
- private static BufferedImage strToImage(String str, int width, int height) {
|
|
|
- BufferedImage textImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
|
|
+ public static void main(String[] args) {
|
|
|
+ try {
|
|
|
+ String qcode = "LKDSLSFD2412341234";
|
|
|
+ String toolName = "名称";
|
|
|
+ List<String> bottomDes = Arrays.asList("长春西高铁综合车间", "存放处",
|
|
|
+ toolName + " - " + "2314321412");
|
|
|
+ encode(qcode, bottomDes, "D:/" + DateUtils.dateTimeNow() + ".jpg");
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static BufferedImage strToImage(String str) {
|
|
|
+ BufferedImage textImage = new BufferedImage(QRCODE_SIZE, FONT_HEIGHT, BufferedImage.TYPE_INT_RGB);
|
|
|
Graphics2D g2 = (Graphics2D) textImage.getGraphics();
|
|
|
//开启文字抗锯齿
|
|
|
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
|
|
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
|
|
g2.setBackground(Color.WHITE);
|
|
|
- g2.clearRect(0, 0, width, height);
|
|
|
+ g2.clearRect(0, 0, QRCODE_SIZE, FONT_HEIGHT);
|
|
|
g2.setPaint(Color.BLACK);
|
|
|
FontRenderContext context = g2.getFontRenderContext();
|
|
|
Font font = new Font("宋体", Font.BOLD, FONT_SIZE);
|
|
|
g2.setFont(font);
|
|
|
LineMetrics lineMetrics = font.getLineMetrics(str, context);
|
|
|
FontMetrics fontMetrics = FontDesignMetrics.getMetrics(font);
|
|
|
- float offset = (width - fontMetrics.stringWidth(str)) / 2;
|
|
|
+ float offset = ((float) QRCODE_SIZE - fontMetrics.stringWidth(str)) / 2;
|
|
|
float y =
|
|
|
- (height + lineMetrics.getAscent() - lineMetrics.getDescent() - lineMetrics.getLeading())
|
|
|
+ (FONT_HEIGHT + lineMetrics.getAscent() - lineMetrics.getDescent() - lineMetrics.getLeading())
|
|
|
/ 2;
|
|
|
g2.drawString(str, (int) offset, (int) y);
|
|
|
return textImage;
|
|
|
@@ -164,7 +190,7 @@ public class QRCodeUtilEx {
|
|
|
|
|
|
public static void encode(String content, String bottomDes, String imgPath, String destPath,
|
|
|
boolean needCompress) throws Exception {
|
|
|
- BufferedImage image = QRCodeUtilEx.createImage(content, bottomDes, imgPath, needCompress);
|
|
|
+ BufferedImage image = createImage(content, bottomDes, imgPath, needCompress);
|
|
|
mkdirs(destPath);
|
|
|
ImageIO.write(image, FORMAT_NAME, new File(destPath));
|
|
|
}
|
|
|
@@ -172,8 +198,8 @@ public class QRCodeUtilEx {
|
|
|
/**
|
|
|
* 获取二维码base64数据,转回图片时前面加上 data:image/png;base64,
|
|
|
*/
|
|
|
- public static String encodeStr(String content, String bottomDes) throws Exception {
|
|
|
- BufferedImage image = QRCodeUtilEx.createImage(content, bottomDes, null, false);
|
|
|
+ public static String encodeStr(String content, List<String> bottomDes) throws Exception {
|
|
|
+ BufferedImage image = createImage(content, bottomDes, null, false);
|
|
|
//io流
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
//写入流中
|
|
|
@@ -190,7 +216,7 @@ public class QRCodeUtilEx {
|
|
|
|
|
|
public static BufferedImage encode(String content, String bottomDes, String imgPath,
|
|
|
boolean needCompress) throws Exception {
|
|
|
- return QRCodeUtilEx.createImage(content, bottomDes, imgPath, needCompress);
|
|
|
+ return createImage(content, bottomDes, imgPath, needCompress);
|
|
|
}
|
|
|
|
|
|
public static void mkdirs(String destPath) throws Exception {
|
|
|
@@ -203,24 +229,31 @@ public class QRCodeUtilEx {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public static void encode(String content, List<String> bottomDes, String destPath)
|
|
|
+ throws Exception {
|
|
|
+ BufferedImage image = createImage(content, bottomDes, destPath, false);
|
|
|
+ mkdirs(destPath);
|
|
|
+ ImageIO.write(image, FORMAT_NAME, new File(destPath));
|
|
|
+ }
|
|
|
+
|
|
|
public static void encode(String content, String bottomDes, String imgPath, String destPath)
|
|
|
throws Exception {
|
|
|
- QRCodeUtilEx.encode(content, bottomDes, imgPath, destPath, false);
|
|
|
+ encode(content, bottomDes, imgPath, destPath, false);
|
|
|
}
|
|
|
|
|
|
public static void encode(String content, String bottomDes, String destPath) throws Exception {
|
|
|
- QRCodeUtilEx.encode(content, bottomDes, null, destPath, false);
|
|
|
+ encode(content, bottomDes, null, destPath, false);
|
|
|
}
|
|
|
|
|
|
public static void encode(String content, String bottomDes, String imgPath, OutputStream output,
|
|
|
boolean needCompress) throws Exception {
|
|
|
- BufferedImage image = QRCodeUtilEx.createImage(content, bottomDes, imgPath, needCompress);
|
|
|
+ BufferedImage image = createImage(content, bottomDes, imgPath, needCompress);
|
|
|
ImageIO.write(image, FORMAT_NAME, output);
|
|
|
}
|
|
|
|
|
|
public static void encode(String content, String bottomDes, OutputStream output)
|
|
|
throws Exception {
|
|
|
- QRCodeUtilEx.encode(content, bottomDes, null, output, false);
|
|
|
+ encode(content, bottomDes, null, output, false);
|
|
|
}
|
|
|
|
|
|
public static String decode(File file) throws Exception {
|
|
|
@@ -239,17 +272,7 @@ public class QRCodeUtilEx {
|
|
|
}
|
|
|
|
|
|
public static String decode(String path) throws Exception {
|
|
|
- return QRCodeUtilEx.decode(new File(path));
|
|
|
- }
|
|
|
-
|
|
|
- public static void main(String[] args) {
|
|
|
- try {
|
|
|
- String str = QRCodeUtilEx.encodeStr("1233444", "测试");
|
|
|
- System.out.println(str);
|
|
|
- QRCodeUtilEx.encode("1233444", "测试", "D:/111.jpg");
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
+ return decode(new File(path));
|
|
|
}
|
|
|
|
|
|
}
|