mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
QrCodeUtil新增SVG格式、Ascii Art字符画格式
This commit is contained in:
parent
0d96bec4cb
commit
2b9da605a7
@ -15,6 +15,7 @@
|
|||||||
* 【core 】 增加替换字符串中第一个指定字符串和最后一个指定字符串方法(pr#2533@Github)
|
* 【core 】 增加替换字符串中第一个指定字符串和最后一个指定字符串方法(pr#2533@Github)
|
||||||
* 【jwt 】 JWT补充部分算法(pr#2546@Github)
|
* 【jwt 】 JWT补充部分算法(pr#2546@Github)
|
||||||
* 【core 】 NumberUtil.roundStr() 修改为使用toPlainString(pr#775@Gitee)
|
* 【core 】 NumberUtil.roundStr() 修改为使用toPlainString(pr#775@Gitee)
|
||||||
|
* 【extra 】 QrCodeUtil新增SVG格式、Ascii Art字符画格式(pr#763@Gitee)
|
||||||
*
|
*
|
||||||
### 🐞Bug修复
|
### 🐞Bug修复
|
||||||
* 【http 】 修复https下可能的Patch、Get请求失效问题(issue#I3Z3DH@Gitee)
|
* 【http 】 修复https下可能的Patch、Get请求失效问题(issue#I3Z3DH@Gitee)
|
||||||
|
@ -130,7 +130,7 @@ public class QrCodeUtil {
|
|||||||
* @since 5.8.6
|
* @since 5.8.6
|
||||||
*/
|
*/
|
||||||
public static String generateAsSvg(String content, QrConfig qrConfig) {
|
public static String generateAsSvg(String content, QrConfig qrConfig) {
|
||||||
BitMatrix bitMatrix = encode(content, qrConfig);
|
final BitMatrix bitMatrix = encode(content, qrConfig);
|
||||||
return toSVG(bitMatrix, qrConfig);
|
return toSVG(bitMatrix, qrConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ public class QrCodeUtil {
|
|||||||
* @since 5.8.6
|
* @since 5.8.6
|
||||||
*/
|
*/
|
||||||
public static String generateAsAsciiArt(String content, QrConfig qrConfig) {
|
public static String generateAsAsciiArt(String content, QrConfig qrConfig) {
|
||||||
BitMatrix bitMatrix = encode(content, qrConfig);
|
final BitMatrix bitMatrix = encode(content, qrConfig);
|
||||||
return toAsciiArt(bitMatrix, qrConfig);
|
return toAsciiArt(bitMatrix, qrConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,12 +627,12 @@ public class QrCodeUtil {
|
|||||||
* @since 5.8.6
|
* @since 5.8.6
|
||||||
*/
|
*/
|
||||||
public static String toAsciiArt(BitMatrix bitMatrix, QrConfig qrConfig) {
|
public static String toAsciiArt(BitMatrix bitMatrix, QrConfig qrConfig) {
|
||||||
int width = bitMatrix.getWidth();
|
final int width = bitMatrix.getWidth();
|
||||||
int height = bitMatrix.getHeight();
|
final int height = bitMatrix.getHeight();
|
||||||
|
|
||||||
|
|
||||||
AnsiElement foreground = qrConfig.foreColor == null ? null : Ansi8BitColor.foreground(rgbToAnsi8BitValue(qrConfig.foreColor));
|
final AnsiElement foreground = qrConfig.foreColor == null ? null : Ansi8BitColor.foreground(rgbToAnsi8BitValue(qrConfig.foreColor));
|
||||||
AnsiElement background = qrConfig.backColor == null ? null : Ansi8BitColor.background(rgbToAnsi8BitValue(qrConfig.backColor));
|
final AnsiElement background = qrConfig.backColor == null ? null : Ansi8BitColor.background(rgbToAnsi8BitValue(qrConfig.backColor));
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for (int i = 0; i <= height; i += 2) {
|
for (int i = 0; i <= height; i += 2) {
|
||||||
@ -663,15 +663,13 @@ public class QrCodeUtil {
|
|||||||
* @since 5.8.6
|
* @since 5.8.6
|
||||||
*/
|
*/
|
||||||
private static int rgbToAnsi8BitValue(int rgb) {
|
private static int rgbToAnsi8BitValue(int rgb) {
|
||||||
int l;
|
final int r = (rgb >> 16) & 0xff;
|
||||||
int r = (rgb >> 16) & 0xff;
|
final int g = (rgb >> 8) & 0xff;
|
||||||
int g = (rgb >> 8) & 0xff;
|
final int b = (rgb) & 0xff;
|
||||||
int b = (rgb) & 0xff;
|
|
||||||
if (r < 0) r += 256;
|
final int l;
|
||||||
if (g < 0) g += 256;
|
|
||||||
if (b < 0) b += 256;
|
|
||||||
if (r == g && g == b) {
|
if (r == g && g == b) {
|
||||||
int i = (int) (NumberUtil.div(NumberUtil.mul(r - 10.625, 23), (255 - 10.625), 0));
|
final int i = (int) (NumberUtil.div(NumberUtil.mul(r - 10.625, 23), (255 - 10.625), 0));
|
||||||
l = i >= 0 ? 232 + i : 0;
|
l = i >= 0 ? 232 + i : 0;
|
||||||
} else {
|
} else {
|
||||||
l = 16 + (int) (36 * NumberUtil.div(NumberUtil.mul(r, 5), 255, 0)) + (int) (6.0 * (g / 256.0 * 6.0)) + (int) (b / 256.0 * 6.0);
|
l = 16 + (int) (36 * NumberUtil.div(NumberUtil.mul(r, 5), 255, 0)) + (int) (6.0 * (g / 256.0 * 6.0)) + (int) (b / 256.0 * 6.0);
|
||||||
|
@ -33,35 +33,35 @@ public class QrCodeUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
// @Ignore
|
@Ignore
|
||||||
public void generateCustomTest() {
|
public void generateCustomTest() {
|
||||||
QrConfig config = new QrConfig();
|
final QrConfig config = new QrConfig();
|
||||||
config.setMargin(0);
|
config.setMargin(0);
|
||||||
config.setForeColor(Color.CYAN);
|
config.setForeColor(Color.CYAN);
|
||||||
// 背景色透明
|
// 背景色透明
|
||||||
config.setBackColor(null);
|
config.setBackColor(null);
|
||||||
config.setErrorCorrection(ErrorCorrectionLevel.H);
|
config.setErrorCorrection(ErrorCorrectionLevel.H);
|
||||||
String path = FileUtil.isWindows() ? "d:/test/qrcodeCustom.png" : "~/Desktop/hutool/qrcodeCustom.png";
|
final String path = FileUtil.isWindows() ? "d:/test/qrcodeCustom.png" : "~/Desktop/hutool/qrcodeCustom.png";
|
||||||
QrCodeUtil.generate("https://hutool.cn/", config, FileUtil.touch(path));
|
QrCodeUtil.generate("https://hutool.cn/", config, FileUtil.touch(path));
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
// @Ignore
|
@Ignore
|
||||||
public void generateNoCustomColorTest() {
|
public void generateNoCustomColorTest() {
|
||||||
QrConfig config = new QrConfig();
|
final QrConfig config = new QrConfig();
|
||||||
config.setMargin(0);
|
config.setMargin(0);
|
||||||
config.setForeColor(null);
|
config.setForeColor(null);
|
||||||
// 背景色透明
|
// 背景色透明
|
||||||
config.setBackColor(null);
|
config.setBackColor(null);
|
||||||
config.setErrorCorrection(ErrorCorrectionLevel.H);
|
config.setErrorCorrection(ErrorCorrectionLevel.H);
|
||||||
String path = FileUtil.isWindows() ? "d:/test/qrcodeCustom.png" : "~/Desktop/hutool/qrcodeCustom.png";
|
final String path = FileUtil.isWindows() ? "d:/test/qrcodeCustom.png" : "~/Desktop/hutool/qrcodeCustom.png";
|
||||||
QrCodeUtil.generate("https://hutool.cn/", config, FileUtil.touch(path));
|
QrCodeUtil.generate("https://hutool.cn/", config, FileUtil.touch(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void generateWithLogoTest() {
|
public void generateWithLogoTest() {
|
||||||
String icon = FileUtil.isWindows() ? "d:/test/pic/face.jpg" : "~/Desktop/hutool/pic/face.jpg";
|
final String icon = FileUtil.isWindows() ? "d:/test/pic/face.jpg" : "~/Desktop/hutool/pic/face.jpg";
|
||||||
String targetPath = FileUtil.isWindows() ? "d:/test/qrcodeWithLogo.jpg" : "~/Desktop/hutool/qrcodeWithLogo.jpg";
|
final String targetPath = FileUtil.isWindows() ? "d:/test/qrcodeWithLogo.jpg" : "~/Desktop/hutool/qrcodeWithLogo.jpg";
|
||||||
QrCodeUtil.generate(//
|
QrCodeUtil.generate(//
|
||||||
"https://hutool.cn/", //
|
"https://hutool.cn/", //
|
||||||
QrConfig.create().setImg(icon), //
|
QrConfig.create().setImg(icon), //
|
||||||
@ -71,7 +71,7 @@ public class QrCodeUtilTest {
|
|||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void decodeTest() {
|
public void decodeTest() {
|
||||||
String decode = QrCodeUtil.decode(FileUtil.file("d:/test/pic/qr.png"));
|
final String decode = QrCodeUtil.decode(FileUtil.file("d:/test/pic/qr.png"));
|
||||||
Console.log(decode);
|
Console.log(decode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,29 +79,29 @@ public class QrCodeUtilTest {
|
|||||||
@Ignore
|
@Ignore
|
||||||
public void decodeTest2() {
|
public void decodeTest2() {
|
||||||
// 条形码
|
// 条形码
|
||||||
String decode = QrCodeUtil.decode(FileUtil.file("d:/test/90.png"));
|
final String decode = QrCodeUtil.decode(FileUtil.file("d:/test/90.png"));
|
||||||
Console.log(decode);
|
Console.log(decode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void generateAsBase64Test() {
|
public void generateAsBase64Test() {
|
||||||
String base64 = QrCodeUtil.generateAsBase64("https://hutool.cn/", new QrConfig(400, 400), "png");
|
final String base64 = QrCodeUtil.generateAsBase64("https://hutool.cn/", new QrConfig(400, 400), "png");
|
||||||
Assert.assertNotNull(base64);
|
Assert.assertNotNull(base64);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void generateAsBase64Test2() {
|
public void generateAsBase64Test2() {
|
||||||
byte[] bytes = FileUtil.readBytes(
|
final byte[] bytes = FileUtil.readBytes(
|
||||||
new File("d:/test/qr.png"));
|
new File("d:/test/qr.png"));
|
||||||
String encode = Base64.encode(bytes);
|
final String encode = Base64.encode(bytes);
|
||||||
String base641 = QrCodeUtil.generateAsBase64("https://hutool.cn/", new QrConfig(400, 400), "png", encode);
|
final String base641 = QrCodeUtil.generateAsBase64("https://hutool.cn/", new QrConfig(400, 400), "png", encode);
|
||||||
Assert.assertNotNull(base641);
|
Assert.assertNotNull(base641);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void generateAsBase64Test3() {
|
public void generateAsBase64Test3() {
|
||||||
String base64 = QrCodeUtil.generateAsBase64("https://hutool.cn/", new QrConfig(400, 400), "svg");
|
final String base64 = QrCodeUtil.generateAsBase64("https://hutool.cn/", new QrConfig(400, 400), "svg");
|
||||||
Assert.assertNotNull(base64);
|
Assert.assertNotNull(base64);
|
||||||
System.out.println(base64);
|
System.out.println(base64);
|
||||||
}
|
}
|
||||||
@ -121,84 +121,91 @@ public class QrCodeUtilTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void generateDataMatrixTest() {
|
public void generateDataMatrixTest() {
|
||||||
QrConfig qrConfig = QrConfig.create();
|
final QrConfig qrConfig = QrConfig.create();
|
||||||
qrConfig.setShapeHint(SymbolShapeHint.FORCE_RECTANGLE);
|
qrConfig.setShapeHint(SymbolShapeHint.FORCE_RECTANGLE);
|
||||||
final BufferedImage image = QrCodeUtil.generate("content111", BarcodeFormat.DATA_MATRIX, qrConfig);
|
final BufferedImage image = QrCodeUtil.generate("content111", BarcodeFormat.DATA_MATRIX, qrConfig);
|
||||||
Assert.assertNotNull(image);
|
Assert.assertNotNull(image);
|
||||||
QrConfig config = QrConfig.create();
|
final QrConfig config = QrConfig.create();
|
||||||
config.setShapeHint(SymbolShapeHint.FORCE_SQUARE);
|
config.setShapeHint(SymbolShapeHint.FORCE_SQUARE);
|
||||||
final BufferedImage imageSquare = QrCodeUtil.generate("content111", BarcodeFormat.DATA_MATRIX, qrConfig);
|
final BufferedImage imageSquare = QrCodeUtil.generate("content111", BarcodeFormat.DATA_MATRIX, qrConfig);
|
||||||
Assert.assertNotNull(imageSquare);
|
Assert.assertNotNull(imageSquare);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore
|
||||||
public void generateSvgTest() {
|
public void generateSvgTest() {
|
||||||
QrConfig qrConfig = QrConfig.create().setImg("d:/test/logo.png")
|
final QrConfig qrConfig = QrConfig.create()
|
||||||
|
.setImg("d:/test/logo.png")
|
||||||
.setForeColor(Color.blue)
|
.setForeColor(Color.blue)
|
||||||
.setBackColor(Color.pink)
|
.setBackColor(Color.pink)
|
||||||
.setRatio(8)
|
.setRatio(8)
|
||||||
.setErrorCorrection(ErrorCorrectionLevel.M)
|
.setErrorCorrection(ErrorCorrectionLevel.M)
|
||||||
.setMargin(1);
|
.setMargin(1);
|
||||||
String svg = QrCodeUtil.generateAsSvg("https://hutool.cn/", qrConfig);
|
final String svg = QrCodeUtil.generateAsSvg("https://hutool.cn/", qrConfig);
|
||||||
Assert.assertNotNull(svg);
|
Assert.assertNotNull(svg);
|
||||||
FileUtil.writeString(svg, FileUtil.touch("d:/test/hutool_qr.svg"),StandardCharsets.UTF_8);
|
FileUtil.writeString(svg, FileUtil.touch("d:/test/hutool_qr.svg"),StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void generateAsciiArtTest() {
|
public void generateAsciiArtTest() {
|
||||||
QrConfig qrConfig = QrConfig.create()
|
final QrConfig qrConfig = QrConfig.create()
|
||||||
.setForeColor(Color.BLUE)
|
.setForeColor(Color.BLUE)
|
||||||
.setBackColor(Color.MAGENTA)
|
.setBackColor(Color.MAGENTA)
|
||||||
.setWidth(0)
|
.setWidth(0)
|
||||||
.setHeight(0).setMargin(1);
|
.setHeight(0).setMargin(1);
|
||||||
String asciiArt = QrCodeUtil.generateAsAsciiArt("https://hutool.cn/",qrConfig);
|
final String asciiArt = QrCodeUtil.generateAsAsciiArt("https://hutool.cn/",qrConfig);
|
||||||
Assert.assertNotNull(asciiArt);
|
Assert.assertNotNull(asciiArt);
|
||||||
System.out.println(asciiArt);
|
//Console.log(asciiArt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void generateAsciiArtNoCustomColorTest() {
|
public void generateAsciiArtNoCustomColorTest() {
|
||||||
QrConfig qrConfig = QrConfig.create()
|
final QrConfig qrConfig = QrConfig.create()
|
||||||
.setForeColor(null)
|
.setForeColor(null)
|
||||||
.setBackColor(null)
|
.setBackColor(null)
|
||||||
.setWidth(0)
|
.setWidth(0)
|
||||||
.setHeight(0).setMargin(1);
|
.setHeight(0).setMargin(1);
|
||||||
String asciiArt = QrCodeUtil.generateAsAsciiArt("https://hutool.cn/",qrConfig);
|
final String asciiArt = QrCodeUtil.generateAsAsciiArt("https://hutool.cn/",qrConfig);
|
||||||
Assert.assertNotNull(asciiArt);
|
Assert.assertNotNull(asciiArt);
|
||||||
System.out.println(asciiArt);
|
//Console.log(asciiArt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore
|
||||||
public void generateToFileTest() {
|
public void generateToFileTest() {
|
||||||
QrConfig qrConfig = QrConfig.create()
|
final QrConfig qrConfig = QrConfig.create()
|
||||||
.setForeColor(Color.BLUE)
|
.setForeColor(Color.BLUE)
|
||||||
.setBackColor(new Color(0,200,255))
|
.setBackColor(new Color(0,200,255))
|
||||||
.setWidth(0)
|
.setWidth(0)
|
||||||
.setHeight(0).setMargin(1);
|
.setHeight(0).setMargin(1);
|
||||||
File qrFile = QrCodeUtil.generate("https://hutool.cn/", qrConfig, FileUtil.touch("d:/test/ascii_art_qr_code.txt"));
|
final 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);
|
final BufferedReader reader = FileUtil.getReader(qrFile, StandardCharsets.UTF_8);
|
||||||
reader.lines().forEach(System.out::println);
|
reader.lines().forEach(System.out::println);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore
|
||||||
public void generateToStreamTest() {
|
public void generateToStreamTest() {
|
||||||
QrConfig qrConfig = QrConfig.create()
|
final QrConfig qrConfig = QrConfig.create()
|
||||||
.setForeColor(Color.BLUE)
|
.setForeColor(Color.BLUE)
|
||||||
.setBackColor(new Color(0,200,255))
|
.setBackColor(new Color(0,200,255))
|
||||||
.setWidth(0)
|
.setWidth(0)
|
||||||
.setHeight(0).setMargin(1);
|
.setHeight(0).setMargin(1);
|
||||||
String filepath = "d:/test/qr_stream_to_txt.txt";
|
final String filepath = "d:/test/qr_stream_to_txt.txt";
|
||||||
try (BufferedOutputStream outputStream = FileUtil.getOutputStream(filepath)) {
|
try (final BufferedOutputStream outputStream = FileUtil.getOutputStream(filepath)) {
|
||||||
QrCodeUtil.generate("https://hutool.cn/", qrConfig,"txt", outputStream);
|
QrCodeUtil.generate("https://hutool.cn/", qrConfig,"txt", outputStream);
|
||||||
}catch (IOException e){
|
}catch (final IOException e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
BufferedReader reader = FileUtil.getReader(filepath, StandardCharsets.UTF_8);
|
final BufferedReader reader = FileUtil.getReader(filepath, StandardCharsets.UTF_8);
|
||||||
reader.lines().forEach(System.out::println);
|
reader.lines().forEach(System.out::println);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore
|
||||||
public void comparePngAndAsciiArtTest() {
|
public void comparePngAndAsciiArtTest() {
|
||||||
QrConfig qrConfig = QrConfig.create()
|
final QrConfig qrConfig = QrConfig.create()
|
||||||
.setForeColor(null)
|
.setForeColor(null)
|
||||||
.setBackColor(null)
|
.setBackColor(null)
|
||||||
.setWidth(0)
|
.setWidth(0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user