diff --git a/hutool-extra/src/main/java/cn/hutool/extra/qrcode/QrCodeUtil.java b/hutool-extra/src/main/java/cn/hutool/extra/qrcode/QrCodeUtil.java
index 287af4595..75448c727 100755
--- a/hutool-extra/src/main/java/cn/hutool/extra/qrcode/QrCodeUtil.java
+++ b/hutool-extra/src/main/java/cn/hutool/extra/qrcode/QrCodeUtil.java
@@ -3,20 +3,15 @@ package cn.hutool.extra.qrcode;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.img.Img;
import cn.hutool.core.img.ImgUtil;
-import cn.hutool.core.lang.ansi.*;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.lang.ansi.Ansi8BitColor;
+import cn.hutool.core.lang.ansi.AnsiElement;
+import cn.hutool.core.lang.ansi.AnsiEncoder;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.Binarizer;
-import com.google.zxing.BinaryBitmap;
-import com.google.zxing.DecodeHintType;
-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.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.HybridBinarizer;
@@ -27,6 +22,7 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@@ -42,6 +38,9 @@ import java.util.Map;
*/
public class QrCodeUtil {
+ public static final String QR_TYPE_SVG = "svg";// SVG矢量图格式
+ public static final String QR_TYPE_TXT = "txt";// Ascii Art字符画文本
+
/**
* 生成代 logo 图片的 Base64 编码格式的二维码,以 String 形式表示
*
@@ -186,8 +185,22 @@ public class QrCodeUtil {
* @return 目标文件
*/
public static File generate(String content, int width, int height, File targetFile) {
- final BufferedImage image = generate(content, width, height);
- ImgUtil.write(image, targetFile);
+ String extName = FileUtil.extName(targetFile);
+ switch (extName) {
+ case QR_TYPE_SVG:
+ String svg = generateAsSvg(content, new QrConfig(width, height));
+ FileUtil.writeString(svg, targetFile, StandardCharsets.UTF_8);
+ break;
+ case QR_TYPE_TXT:
+ String txt = generateAsAsciiArt(content, new QrConfig(width, height));
+ FileUtil.writeString(txt, targetFile, StandardCharsets.UTF_8);
+ break;
+ default:
+ final BufferedImage image = generate(content, width, height);
+ ImgUtil.write(image, targetFile);
+ break;
+ }
+
return targetFile;
}
@@ -201,23 +214,48 @@ public class QrCodeUtil {
* @since 4.1.2
*/
public static File generate(String content, QrConfig config, File targetFile) {
- final BufferedImage image = generate(content, config);
- ImgUtil.write(image, targetFile);
+ String extName = FileUtil.extName(targetFile);
+ switch (extName) {
+ case QR_TYPE_SVG:
+ final String svg = generateAsSvg(content, config);
+ FileUtil.writeString(svg, targetFile, StandardCharsets.UTF_8);
+ break;
+ case QR_TYPE_TXT:
+ final String txt = generateAsAsciiArt(content, config);
+ FileUtil.writeString(txt, targetFile, StandardCharsets.UTF_8);
+ break;
+ default:
+ final BufferedImage image = generate(content, config);
+ ImgUtil.write(image, targetFile);
+ break;
+ }
return targetFile;
}
/**
* 生成二维码到输出流
*
- * @param content 文本内容
- * @param width 宽度
- * @param height 高度
- * @param imageType 图片类型(图片扩展名),见{@link ImgUtil}
- * @param out 目标流
+ * @param content 文本内容
+ * @param width 宽度
+ * @param height 高度
+ * @param targetType 类型(图片扩展名),见{@link #QR_TYPE_SVG}、 {@link #QR_TYPE_TXT}、{@link ImgUtil}
+ * @param out 目标流
*/
- public static void generate(String content, int width, int height, String imageType, OutputStream out) {
- final BufferedImage image = generate(content, width, height);
- ImgUtil.write(image, imageType, out);
+ public static void generate(String content, int width, int height, String targetType, OutputStream out) {
+ switch (targetType) {
+ case QR_TYPE_SVG:
+ final String svg = generateAsSvg(content, new QrConfig(width, height));
+ IoUtil.writeUtf8(out, false, svg);
+ break;
+ case QR_TYPE_TXT:
+ final String txt = generateAsAsciiArt(content, new QrConfig(width, height));
+ IoUtil.writeUtf8(out, false, txt);
+ break;
+ default:
+ final BufferedImage image = generate(content, width, height);
+ ImgUtil.write(image, targetType, out);
+ break;
+ }
}
/**
@@ -225,13 +263,25 @@ public class QrCodeUtil {
*
* @param content 文本内容
* @param config 二维码配置,包括长、宽、边距、颜色等
- * @param imageType 图片类型(图片扩展名),见{@link ImgUtil}
+ * @param targetType 类型(图片扩展名),见{@link #QR_TYPE_SVG}、 {@link #QR_TYPE_TXT}、{@link ImgUtil}
* @param out 目标流
* @since 4.1.2
*/
- public static void generate(String content, QrConfig config, String imageType, OutputStream out) {
- final BufferedImage image = generate(content, config);
- ImgUtil.write(image, imageType, out);
+ public static void generate(String content, QrConfig config, String targetType, OutputStream out) {
+ switch (targetType) {
+ case QR_TYPE_SVG:
+ final String svg = generateAsSvg(content, config);
+ IoUtil.writeUtf8(out, false, svg);
+ break;
+ case QR_TYPE_TXT:
+ final String txt = generateAsAsciiArt(content, config);
+ IoUtil.writeUtf8(out, false, txt);
+ break;
+ default:
+ final BufferedImage image = generate(content, config);
+ ImgUtil.write(image, targetType, out);
+ break;
+ }
}
/**
@@ -479,7 +529,7 @@ public class QrCodeUtil {
* @since 5.8.6
*/
public static String toSVG(BitMatrix matrix, QrConfig qrConfig) {
- return toSVG(matrix, qrConfig.getForeColor(), qrConfig.getBackColor(), qrConfig.img, qrConfig.getRatio());
+ return toSVG(matrix, qrConfig.foreColor, qrConfig.backColor, qrConfig.img, qrConfig.getRatio());
}
/**
@@ -524,16 +574,24 @@ public class QrCodeUtil {
logoY = (qrHeight - logoHeight) / 2;
}
+
Color fore = new Color(foreColor, true);
- Color back = new Color(backColor, true);
- return "";
+
+ StringBuilder result = StrUtil.builder();
+ result.append("");
+ return result.toString();
}
/**
@@ -547,8 +605,9 @@ public class QrCodeUtil {
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
- AnsiElement foreground = Ansi8BitColor.foreground(rgbToAnsi8BitValue(qrConfig.getForeColor()));
- AnsiElement background = Ansi8BitColor.background(rgbToAnsi8BitValue(qrConfig.getBackColor()));
+
+ AnsiElement foreground = qrConfig.foreColor == null ? null : Ansi8BitColor.foreground(rgbToAnsi8BitValue(qrConfig.foreColor));
+ AnsiElement background = qrConfig.backColor == null ? null : Ansi8BitColor.background(rgbToAnsi8BitValue(qrConfig.backColor));
StringBuilder builder = new StringBuilder();
for (int i = 0; i <= height; i += 2) {
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/qrcode/QrConfig.java b/hutool-extra/src/main/java/cn/hutool/extra/qrcode/QrConfig.java
index 91675cc16..4d5a388d8 100755
--- a/hutool-extra/src/main/java/cn/hutool/extra/qrcode/QrConfig.java
+++ b/hutool-extra/src/main/java/cn/hutool/extra/qrcode/QrConfig.java
@@ -30,7 +30,7 @@ public class QrConfig {
/** 长 */
protected int height;
/** 前景色(二维码颜色) */
- protected int foreColor = BLACK;
+ protected Integer foreColor = BLACK;
/** 背景色,默认白色,null表示透明 */
protected Integer backColor = WHITE;
/** 边距1~4 */
diff --git a/hutool-extra/src/test/java/cn/hutool/extra/qrcode/QrCodeUtilTest.java b/hutool-extra/src/test/java/cn/hutool/extra/qrcode/QrCodeUtilTest.java
index 799e23361..ab07bde11 100755
--- a/hutool-extra/src/test/java/cn/hutool/extra/qrcode/QrCodeUtilTest.java
+++ b/hutool-extra/src/test/java/cn/hutool/extra/qrcode/QrCodeUtilTest.java
@@ -4,19 +4,19 @@ import cn.hutool.core.codec.Base64;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Console;
-import cn.hutool.core.lang.ansi.Ansi8BitColor;
-import cn.hutool.core.lang.ansi.AnsiEncoder;
import com.google.zxing.BarcodeFormat;
-import com.google.zxing.common.BitMatrix;
import com.google.zxing.datamatrix.encoder.SymbolShapeHint;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
-import java.awt.Color;
+import java.awt.*;
import java.awt.image.BufferedImage;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
@@ -41,7 +41,7 @@ public class QrCodeUtilTest {
// 背景色透明
config.setBackColor(null);
config.setErrorCorrection(ErrorCorrectionLevel.H);
- String path = FileUtil.isWindows() ? "d:/test/qrcodeCustom.png" : "~/Desktop/hutool/qrcodeCustom.png";
+ String path = FileUtil.isWindows() ? "d:/test/qrcodeCustom.txt" : "~/Desktop/hutool/qrcodeCustom.svg";
QrCodeUtil.generate("https://hutool.cn/", config, FileUtil.touch(path));
}
@@ -120,14 +120,13 @@ public class QrCodeUtilTest {
.setMargin(1);
String svg = QrCodeUtil.generateAsSvg("https://hutool.cn/", qrConfig);
Assert.assertNotNull(svg);
- FileUtil.writeString(svg, "d:/test/qr.svg", StandardCharsets.UTF_8);
}
@Test
public void generateAsciiArtTest() {
QrConfig qrConfig = QrConfig.create()
- .setForeColor(new Color(0,255,0))
- .setBackColor(new Color(0,0,0))
+ .setForeColor(new Color(255,0,255))
+ .setBackColor(new Color(0,255,0))
.setWidth(0)
.setHeight(0).setMargin(1);
String asciiArt = QrCodeUtil.generateAsAsciiArt("https://hutool.cn/",qrConfig);
@@ -135,4 +134,33 @@ public class QrCodeUtilTest {
System.out.println(asciiArt);
}
+ @Test
+ public void generateToFileTest() {
+ QrConfig qrConfig = QrConfig.create()
+ .setForeColor(Color.BLUE)
+ .setBackColor(new Color(0,200,255))
+ .setWidth(0)
+ .setHeight(0).setMargin(1);
+ File qrFile = QrCodeUtil.generate("https://hutool.cn/", qrConfig, FileUtil.touch("d:/test/ascii_art_qr_code.txt"));
+ BufferedReader reader = FileUtil.getReader(qrFile, StandardCharsets.UTF_8);
+ reader.lines().forEach(System.out::println);
+ }
+
+ @Test
+ public void generateToStreamTest() {
+ QrConfig qrConfig = QrConfig.create()
+ .setForeColor(Color.BLUE)
+ .setBackColor(new Color(0,200,255))
+ .setWidth(0)
+ .setHeight(0).setMargin(1);
+ String filepath = "d:/test/qr_stream_to_txt.txt";
+ try (BufferedOutputStream outputStream = FileUtil.getOutputStream(filepath)) {
+ QrCodeUtil.generate("https://hutool.cn/", qrConfig,"txt", outputStream);
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ BufferedReader reader = FileUtil.getReader(filepath, StandardCharsets.UTF_8);
+ reader.lines().forEach(System.out::println);
+ }
+
}