add methods

This commit is contained in:
Looly 2022-09-18 11:20:28 +08:00
parent 705a15c3e5
commit 0e287161bd
8 changed files with 200 additions and 100 deletions

View File

@ -449,13 +449,13 @@ public class UrlBuilderTest {
@SuppressWarnings("ConstantConditions")
@Test
public void issues2503Test() throws URISyntaxException {
String duplicate = UrlBuilder.ofHttp("127.0.0.1:8080")
final String duplicate = UrlBuilder.ofHttp("127.0.0.1:8080")
.addQuery("param[0].field", "编码")
.toURI()
.toString();
Assert.assertEquals("http://127.0.0.1:8080?param%5B0%5D.field=%E7%BC%96%E7%A0%81", duplicate);
String normal = UrlBuilder.ofHttp("127.0.0.1:8080")
final String normal = UrlBuilder.ofHttp("127.0.0.1:8080")
.addQuery("param[0].field", "编码")
.toURL()
.toURI()

View File

@ -20,7 +20,7 @@ public class QrAsciiArt {
* @param matrix {@link BitMatrix}
* @param qrConfig {@link QrConfig}
*/
public QrAsciiArt(BitMatrix matrix, QrConfig qrConfig) {
public QrAsciiArt(final BitMatrix matrix, final QrConfig qrConfig) {
this.matrix = matrix;
this.qrConfig = qrConfig;
}
@ -34,12 +34,12 @@ public class QrAsciiArt {
final AnsiElement foreground = qrConfig.foreColor == null ? null : ColorUtil.toAnsiColor(qrConfig.foreColor, true, false);
final AnsiElement background = qrConfig.backColor == null ? null : ColorUtil.toAnsiColor(qrConfig.backColor, true, true);
StringBuilder builder = new StringBuilder();
final StringBuilder builder = new StringBuilder();
for (int i = 0; i <= height; i += 2) {
StringBuilder rowBuilder = new StringBuilder();
final StringBuilder rowBuilder = new StringBuilder();
for (int j = 0; j < width; j++) {
boolean tp = matrix.get(i, j);
boolean bt = i + 1 >= height || matrix.get(i + 1, j);
final boolean tp = matrix.get(i, j);
final boolean bt = i + 1 >= height || matrix.get(i + 1, j);
if (tp && bt) {
rowBuilder.append(' ');//'\u0020'
} else if (tp) {

View File

@ -41,7 +41,7 @@ public class QrCodeUtil {
* @param logoBase64 logo 图片的 base64 编码
* @return 图片 Base64 编码字符串
*/
public static String generateAsBase64(String content, QrConfig qrConfig, String targetType, String logoBase64) {
public static String generateAsBase64(final String content, final QrConfig qrConfig, final String targetType, final String logoBase64) {
return generateAsBase64DataUri(content, qrConfig, targetType, Base64.decode(logoBase64));
}
@ -54,7 +54,7 @@ public class QrCodeUtil {
* @param logo logo 图片的byte[]
* @return 图片 Base64 编码字符串
*/
public static String generateAsBase64DataUri(String content, QrConfig qrConfig, String targetType, byte[] logo) {
public static String generateAsBase64DataUri(final String content, final QrConfig qrConfig, final String targetType, final byte[] logo) {
return generateAsBase64DataUri(content, qrConfig.setImg(ImgUtil.toImage(logo)), targetType);
}
@ -293,7 +293,7 @@ public class QrCodeUtil {
* @return SVG矢量图字符串
* @since 5.8.6
*/
public static String generateAsSvg(String content, QrConfig qrConfig) {
public static String generateAsSvg(final String content, final QrConfig qrConfig) {
return toSVG(encode(content, qrConfig), qrConfig);
}
@ -304,7 +304,7 @@ public class QrCodeUtil {
* @param config {@link QrConfig}
* @return SVG矢量图字符串
*/
public static String toSVG(BitMatrix matrix, QrConfig config) {
public static String toSVG(final BitMatrix matrix, final QrConfig config) {
return new QrSVG(matrix, config).toString();
}
@ -316,7 +316,7 @@ public class QrCodeUtil {
* @return ASCII Art字符画形式的二维码
* @since 5.8.6
*/
public static String generateAsAsciiArt(String content, QrConfig qrConfig) {
public static String generateAsAsciiArt(final String content, final QrConfig qrConfig) {
return toAsciiArt(encode(content, qrConfig), qrConfig);
}
@ -327,7 +327,7 @@ public class QrCodeUtil {
* @return ASCII Art字符画形式的二维码
* @since 5.8.6
*/
public static String toAsciiArt(BitMatrix bitMatrix, QrConfig qrConfig) {
public static String toAsciiArt(final BitMatrix bitMatrix, final QrConfig qrConfig) {
return new QrAsciiArt(bitMatrix, qrConfig).toString();
}
}

View File

@ -21,7 +21,7 @@ public class QrEncoder implements Encoder<CharSequence, BitMatrix> {
* @param config {@link QrConfig}
* @return QrEncoder
*/
public static QrEncoder of(QrConfig config) {
public static QrEncoder of(final QrConfig config) {
return new QrEncoder(config);
}
@ -32,12 +32,12 @@ public class QrEncoder implements Encoder<CharSequence, BitMatrix> {
*
* @param config {@link QrConfig}
*/
public QrEncoder(QrConfig config) {
public QrEncoder(final QrConfig config) {
this.config = ObjUtil.defaultIfNull(config, QrConfig::of);
}
@Override
public BitMatrix encode(CharSequence content) {
public BitMatrix encode(final CharSequence content) {
final MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
final BitMatrix bitMatrix;

View File

@ -2,6 +2,7 @@ package cn.hutool.extra.qrcode;
import cn.hutool.core.text.StrUtil;
import cn.hutool.swing.img.ImgUtil;
import cn.hutool.swing.img.color.ColorUtil;
import com.google.zxing.common.BitMatrix;
import java.awt.Color;
@ -22,7 +23,7 @@ public class QrSVG {
* @param matrix {@link BitMatrix}
* @param qrConfig {@link QrConfig}
*/
public QrSVG(BitMatrix matrix, QrConfig qrConfig) {
public QrSVG(final BitMatrix matrix, final QrConfig qrConfig) {
this.matrix = matrix;
this.qrConfig = qrConfig;
}
@ -35,9 +36,9 @@ public class QrSVG {
final int ratio = qrConfig.ratio;
final StringBuilder sb = new StringBuilder();
int qrWidth = matrix.getWidth();
final int qrWidth = matrix.getWidth();
int qrHeight = matrix.getHeight();
int moduleHeight = (qrHeight == 1) ? qrWidth / 2 : 1;
final int moduleHeight = (qrHeight == 1) ? qrWidth / 2 : 1;
for (int y = 0; y < qrHeight; y++) {
for (int x = 0; x < qrWidth; x++) {
if (matrix.get(x, y)) {
@ -69,16 +70,16 @@ public class QrSVG {
final StringBuilder result = StrUtil.builder();
result.append("<svg width=\"").append(qrWidth).append("\" height=\"").append(qrHeight).append("\" \n");
if (backColor != null) {
Color back = new Color(backColor, true);
result.append("style=\"background-color:rgba(").append(back.getRed()).append(",").append(back.getGreen()).append(",").append(back.getBlue()).append(",").append(back.getAlpha()).append(")\"\n");
final Color back = new Color(backColor, true);
result.append("style=\"background-color:").append(ColorUtil.toCssRgba(back)).append("\"\n");
}
result.append("viewBox=\"0 0 ").append(qrWidth).append(" ").append(qrHeight).append("\" \n");
result.append("xmlns=\"http://www.w3.org/2000/svg\" \n");
result.append("xmlns:xlink=\"http://www.w3.org/1999/xlink\" >\n");
result.append("<path d=\"").append(sb).append("\" ");
if (foreColor != null) {
Color fore = new Color(foreColor, true);
result.append("stroke=\"rgba(").append(fore.getRed()).append(",").append(fore.getGreen()).append(",").append(fore.getBlue()).append(",").append(fore.getAlpha()).append(")\"");
final Color fore = new Color(foreColor, true);
result.append("stroke=\"").append(ColorUtil.toCssRgba(fore)).append("\"");
}
result.append(" /> \n");
if (StrUtil.isNotBlank(logoBase64)) {

View File

@ -0,0 +1,28 @@
package cn.hutool.http;
import cn.hutool.core.lang.Console;
import cn.hutool.core.map.MapUtil;
import org.junit.Ignore;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
public class Issue2531Test {
@Test
@Ignore
public void getTest(){
final Map<String,String> map = new HashMap<>();
map.put("str","+123");
final String queryParam = MapUtil.join(map, "&", "=");//返回str=+123
Console.log(queryParam);
final HttpRequest request = HttpUtil.createGet("http://localhost:8888/formTest?" + queryParam);
//request.setUrl("http://localhost:8888/formTest" + "?" + queryParam);
//noinspection resource
final HttpResponse execute = request.execute();
Console.log(execute.body());
}
}

View File

@ -4,8 +4,8 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.ansi.Ansi4BitColor;
import cn.hutool.core.lang.ansi.Ansi8BitColor;
import cn.hutool.core.lang.ansi.AnsiElement;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import java.awt.Color;
@ -22,11 +22,68 @@ import java.util.Random;
*/
public class ColorUtil {
private static final Map<String, Color> COLOR_MAPPING;
static {
final Map<String, Color> colorMap = MapUtil
.builder("BLACK", Color.BLACK)
.put("WHITE", Color.WHITE)
.put("LIGHTGRAY", Color.LIGHT_GRAY)
.put("LIGHT_GRAY", Color.LIGHT_GRAY)
.put("GRAY", Color.GRAY)
.put("DARKGRAY", Color.DARK_GRAY)
.put("DARK_GRAY", Color.DARK_GRAY)
.put("RED", Color.RED)
.put("PINK", Color.PINK)
.put("ORANGE", Color.ORANGE)
.put("YELLOW", Color.YELLOW)
.put("GREEN", Color.GREEN)
.put("MAGENTA", Color.MAGENTA)
.put("CYAN", Color.CYAN)
.put("BLUE", Color.BLUE)
// 暗金色
.put("DARKGOLD", hexToColor("#9e7e67"))
.put("DARK_GOLD", hexToColor("#9e7e67"))
// 亮金色
.put("LIGHTGOLD", hexToColor("#ac9c85"))
.put("LIGHT_GOLD", hexToColor("#ac9c85"))
.build();
COLOR_MAPPING = MapUtil.view(colorMap);
}
/**
* RGB颜色范围上限
*/
private static final int RGB_COLOR_BOUND = 256;
/**
* 将颜色转换为CSS的rgba表示形式输出结果格式为rgba(red, green, blue)
* @param color AWT颜色
* @return rgb(red, green, blue)
*/
public static String toCssRgb(final Color color){
return StrUtil.builder()
.append("rgb(")
.append(color.getRed()).append(",")
.append(color.getGreen()).append(",")
.append(color.getBlue()).append(")")
.toString();
}
/**
* 将颜色转换为CSS的rgba表示形式输出结果格式为rgba(red, green, blue, alpha)
* @param color AWT颜色
* @return rgba(red, green, blue, alpha)
*/
public static String toCssRgba(final Color color){
return StrUtil.builder()
.append("rgba(")
.append(color.getRed()).append(",")
.append(color.getGreen()).append(",")
.append(color.getBlue()).append(",")
.append(color.getAlpha() / 255D).append(")")
.toString();
}
/**
* Color对象转16进制表示例如#fcf6d6
*
@ -34,7 +91,7 @@ public class ColorUtil {
* @return 16进制的颜色值例如#fcf6d6
* @since 4.1.14
*/
public static String toHex(Color color) {
public static String toHex(final Color color) {
return toHex(color.getRed(), color.getGreen(), color.getBlue());
}
@ -46,7 +103,7 @@ public class ColorUtil {
* @param b (B)
* @return 返回字符串形式的 十六进制颜色码
*/
public static String toHex(int r, int g, int b) {
public static String toHex(final int r, final int g, final int b) {
// rgb 小于 255
if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
throw new IllegalArgumentException("RGB must be 0~255!");
@ -61,6 +118,7 @@ public class ColorUtil {
* 1. 颜色的英文名大小写皆可
* 2. 16进制表示例如#fcf6d6或者$fcf6d6
* 3. RGB形式例如13,148,252
* 4. RGBA形式例如13,148,252,1
* </pre>
* <p>
* 方法来自com.lnwazg.kit
@ -75,57 +133,40 @@ public class ColorUtil {
}
colorName = colorName.toUpperCase();
if ("BLACK".equals(colorName)) {
return Color.BLACK;
} else if ("WHITE".equals(colorName)) {
return Color.WHITE;
} else if ("LIGHTGRAY".equals(colorName) || "LIGHT_GRAY".equals(colorName)) {
return Color.LIGHT_GRAY;
} else if ("GRAY".equals(colorName)) {
return Color.GRAY;
} else if ("DARKGRAY".equals(colorName) || "DARK_GRAY".equals(colorName)) {
return Color.DARK_GRAY;
} else if ("RED".equals(colorName)) {
return Color.RED;
} else if ("PINK".equals(colorName)) {
return Color.PINK;
} else if ("ORANGE".equals(colorName)) {
return Color.ORANGE;
} else if ("YELLOW".equals(colorName)) {
return Color.YELLOW;
} else if ("GREEN".equals(colorName)) {
return Color.GREEN;
} else if ("MAGENTA".equals(colorName)) {
return Color.MAGENTA;
} else if ("CYAN".equals(colorName)) {
return Color.CYAN;
} else if ("BLUE".equals(colorName)) {
return Color.BLUE;
} else if ("DARKGOLD".equals(colorName)) {
// 暗金色
return hexToColor("#9e7e67");
} else if ("LIGHTGOLD".equals(colorName)) {
// 亮金色
return hexToColor("#ac9c85");
} else if (StrUtil.startWith(colorName, '#')) {
// 预定义颜色别名
final Color color = COLOR_MAPPING.get(colorName);
if(null != color){
return color;
}
// 16进制
if (StrUtil.startWith(colorName, '#')) {
return hexToColor(colorName);
} else if (StrUtil.startWith(colorName, '$')) {
// 由于#在URL传输中无法传输因此用$代替#
return hexToColor("#" + colorName.substring(1));
} else {
// rgb值
final List<String> rgb = StrUtil.split(colorName, ',');
if (3 == rgb.size()) {
final Integer r = Convert.toInt(rgb.get(0));
final Integer g = Convert.toInt(rgb.get(1));
final Integer b = Convert.toInt(rgb.get(2));
if (false == ArrayUtil.hasNull(r, g, b)) {
return new Color(r, g, b);
}
} else {
return null;
}
}
// RGB值和RGBA
final List<String> rgb = StrUtil.split(colorName, ',');
final int size = rgb.size();
if(3 == size){
// RGB
final Integer[] rgbIntegers = Convert.toIntArray(rgb);
return new Color(rgbIntegers[0], rgbIntegers[1], rgbIntegers[2]);
}
if(4 == size){
// RGBA
final Float[] rgbFloats = Convert.toFloatArray(rgb);
Float a = rgbFloats[3];
if(a < 1){
// 识别CSS形式
a *= 255;
}
return new Color(rgbFloats[0], rgbFloats[1], rgbFloats[2], a);
}
return null;
}
@ -136,7 +177,7 @@ public class ColorUtil {
* @return {@link Color}
* @since 4.1.14
*/
public static Color getColor(int rgb) {
public static Color getColor(final int rgb) {
return new Color(rgb);
}
@ -147,7 +188,7 @@ public class ColorUtil {
* @return {@link Color}
* @since 4.1.14
*/
public static Color hexToColor(String hex) {
public static Color hexToColor(final String hex) {
return getColor(Integer.parseInt(StrUtil.removePrefix(hex, "#"), 16));
}
@ -158,18 +199,20 @@ public class ColorUtil {
* @param color2 颜色2
* @return 叠加后的颜色
*/
public static Color add(Color color1, Color color2) {
double r1 = color1.getRed();
double g1 = color1.getGreen();
double b1 = color1.getBlue();
double a1 = color1.getAlpha();
double r2 = color2.getRed();
double g2 = color2.getGreen();
double b2 = color2.getBlue();
double a2 = color2.getAlpha();
int r = (int) ((r1 * a1 / 255 + r2 * a2 / 255) / (a1 / 255 + a2 / 255));
int g = (int) ((g1 * a1 / 255 + g2 * a2 / 255) / (a1 / 255 + a2 / 255));
int b = (int) ((b1 * a1 / 255 + b2 * a2 / 255) / (a1 / 255 + a2 / 255));
public static Color add(final Color color1, final Color color2) {
final double r1 = color1.getRed();
final double g1 = color1.getGreen();
final double b1 = color1.getBlue();
final double a1 = color1.getAlpha();
final double r2 = color2.getRed();
final double g2 = color2.getGreen();
final double b2 = color2.getBlue();
final double a2 = color2.getAlpha();
final int r = (int) ((r1 * a1 / 255 + r2 * a2 / 255) / (a1 / 255 + a2 / 255));
final int g = (int) ((g1 * a1 / 255 + g2 * a2 / 255) / (a1 / 255 + a2 / 255));
final int b = (int) ((b1 * a1 / 255 + b2 * a2 / 255) / (a1 / 255 + a2 / 255));
return new Color(r, g, b);
}
@ -205,7 +248,7 @@ public class ColorUtil {
* @param isBackground 是否背景色
* @return ANSI颜色
*/
public static AnsiElement toAnsiColor(int rgb, boolean is8Bit, boolean isBackground) {
public static AnsiElement toAnsiColor(final int rgb, final boolean is8Bit, final boolean isBackground) {
return toAnsiColor(getColor(rgb), is8Bit, isBackground);
}
@ -217,7 +260,7 @@ public class ColorUtil {
* @param isBackground 是否背景色
* @return ANSI颜色
*/
public static AnsiElement toAnsiColor(Color color, boolean is8Bit, boolean isBackground) {
public static AnsiElement toAnsiColor(final Color color, final boolean is8Bit, final boolean isBackground) {
if (is8Bit) {
final Ansi8BitColor ansiElement = (Ansi8BitColor) Ansi8bitMapping.INSTANCE.lookupClosest(color);
if (isBackground) {
@ -241,16 +284,16 @@ public class ColorUtil {
* @return {@link String} #ffffff
* @since 5.6.7
*/
public static String getMainColor(BufferedImage image, int[]... rgbFilters) {
public static String getMainColor(final BufferedImage image, final int[]... rgbFilters) {
int r, g, b;
Map<String, Long> countMap = new HashMap<>();
int width = image.getWidth();
int height = image.getHeight();
int minx = image.getMinX();
int miny = image.getMinY();
final Map<String, Long> countMap = new HashMap<>();
final int width = image.getWidth();
final int height = image.getHeight();
final int minx = image.getMinX();
final int miny = image.getMinY();
for (int i = minx; i < width; i++) {
for (int j = miny; j < height; j++) {
int pixel = image.getRGB(i, j);
final int pixel = image.getRGB(i, j);
r = (pixel & 0xff0000) >> 16;
g = (pixel & 0xff00) >> 8;
b = (pixel & 0xff);
@ -262,9 +305,9 @@ public class ColorUtil {
}
String maxColor = null;
long maxCount = 0;
for (Map.Entry<String, Long> entry : countMap.entrySet()) {
String key = entry.getKey();
Long count = entry.getValue();
for (final Map.Entry<String, Long> entry : countMap.entrySet()) {
final String key = entry.getKey();
final Long count = entry.getValue();
if (count > maxCount) {
maxColor = key;
maxCount = count;
@ -289,9 +332,9 @@ public class ColorUtil {
* @param rgbFilters 颜色过滤器
* @return 是否匹配
*/
private static boolean matchFilters(int r, int g, int b, int[]... rgbFilters) {
private static boolean matchFilters(final int r, final int g, final int b, final int[]... rgbFilters) {
if (rgbFilters != null && rgbFilters.length > 0) {
for (int[] rgbFilter : rgbFilters) {
for (final int[] rgbFilter : rgbFilters) {
if (r == rgbFilter[0] && g == rgbFilter[1] && b == rgbFilter[2]) {
return true;
}

View File

@ -0,0 +1,28 @@
package cn.hutool.swing.img;
import cn.hutool.swing.img.color.ColorUtil;
import org.junit.Assert;
import org.junit.Test;
import java.awt.Color;
public class ColorUtilTest {
@Test
public void getColorTest(){
final Color blue = ColorUtil.getColor("blue");
Assert.assertEquals(Color.BLUE, blue);
}
@Test
public void toCssRgbTest(){
final String s = ColorUtil.toCssRgb(Color.BLUE);
Assert.assertEquals("rgb(0,0,255)", s);
}
@Test
public void toCssRgbaTest(){
final String s = ColorUtil.toCssRgba(Color.BLUE);
Assert.assertEquals("rgba(0,0,255,1.0)", s);
}
}