mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add methods
This commit is contained in:
parent
838a2c45a6
commit
8ddb2b425c
@ -3,7 +3,7 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.7.8 (2021-08-09)
|
||||
# 5.7.8 (2021-08-10)
|
||||
|
||||
### 🐣新特性
|
||||
* 【core 】 MapProxy支持return this的setter方法(pr#392@Gitee)
|
||||
@ -14,6 +14,7 @@
|
||||
|
||||
### 🐞Bug修复
|
||||
* 【core 】 改进NumberChineseFormatter算法,补充完整单元测试,解决零问题
|
||||
* 【core 】 修复Img变换操作图片格式问题(issue#I44JRB@Gitee)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -27,9 +27,7 @@ import java.awt.color.ColorSpace;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorConvertOp;
|
||||
import java.awt.image.CropImageFilter;
|
||||
import java.awt.image.FilteredImageSource;
|
||||
import java.awt.image.ImageFilter;
|
||||
@ -230,19 +228,19 @@ public class Img implements Serializable {
|
||||
// 自动修正负数
|
||||
scale = -scale;
|
||||
}
|
||||
|
||||
final Image srcImg = getValidSrcImg();
|
||||
|
||||
// PNG图片特殊处理
|
||||
if (ImgUtil.IMAGE_TYPE_PNG.equals(this.targetImageType)) {
|
||||
final AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(scale, scale), null);
|
||||
this.targetImage = op.filter(ImgUtil.toBufferedImage(srcImg), null);
|
||||
// 修正float转double导致的精度丢失
|
||||
final double scaleDouble = NumberUtil.toDouble(scale);
|
||||
this.targetImage = ImgUtil.transform(AffineTransform.getScaleInstance(scaleDouble, scaleDouble),
|
||||
ImgUtil.toBufferedImage(srcImg, this.targetImageType));
|
||||
} else {
|
||||
final String scaleStr = Float.toString(scale);
|
||||
// 缩放后的图片宽
|
||||
int width = NumberUtil.mul(Integer.toString(srcImg.getWidth(null)), scaleStr).intValue();
|
||||
final int width = NumberUtil.mul((Number) srcImg.getWidth(null), scale).intValue();
|
||||
// 缩放后的图片高
|
||||
int height = NumberUtil.mul(Integer.toString(srcImg.getHeight(null)), scaleStr).intValue();
|
||||
final int height = NumberUtil.mul((Number) srcImg.getHeight(null), scale).intValue();
|
||||
scale(width, height);
|
||||
}
|
||||
return this;
|
||||
@ -277,8 +275,8 @@ public class Img implements Serializable {
|
||||
double sy = NumberUtil.div(height, srcHeight);
|
||||
|
||||
if (ImgUtil.IMAGE_TYPE_PNG.equals(this.targetImageType)) {
|
||||
final AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(sx, sy), null);
|
||||
this.targetImage = op.filter(ImgUtil.toBufferedImage(srcImg), null);
|
||||
this.targetImage = ImgUtil.transform(AffineTransform.getScaleInstance(sx, sy),
|
||||
ImgUtil.toBufferedImage(srcImg, this.targetImageType));
|
||||
} else {
|
||||
this.targetImage = srcImg.getScaledInstance(width, height, scaleType);
|
||||
}
|
||||
@ -347,8 +345,7 @@ public class Img implements Serializable {
|
||||
fixRectangle(rectangle, srcImage.getWidth(null), srcImage.getHeight(null));
|
||||
|
||||
final ImageFilter cropFilter = new CropImageFilter(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
|
||||
final Image image = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(srcImage.getSource(), cropFilter));
|
||||
this.targetImage = ImgUtil.toBufferedImage(image);
|
||||
this.targetImage = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(srcImage.getSource(), cropFilter));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -428,8 +425,7 @@ public class Img implements Serializable {
|
||||
* @return this
|
||||
*/
|
||||
public Img gray() {
|
||||
final ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
|
||||
this.targetImage = op.filter(ImgUtil.toBufferedImage(getValidSrcImg()), null);
|
||||
this.targetImage = ImgUtil.colorConvert(ColorSpace.getInstance(ColorSpace.CS_GRAY), getValidSrcBufferedImg());
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -456,7 +452,7 @@ public class Img implements Serializable {
|
||||
* @return 处理后的图像
|
||||
*/
|
||||
public Img pressText(String pressText, Color color, Font font, int x, int y, float alpha) {
|
||||
final BufferedImage targetImage = ImgUtil.toBufferedImage(getValidSrcImg());
|
||||
final BufferedImage targetImage = ImgUtil.toBufferedImage(getValidSrcImg(), this.targetImageType);
|
||||
final Graphics2D g = targetImage.createGraphics();
|
||||
|
||||
if (null == font) {
|
||||
@ -477,6 +473,7 @@ public class Img implements Serializable {
|
||||
new Point(x, y));
|
||||
}
|
||||
|
||||
// 收笔
|
||||
g.dispose();
|
||||
this.targetImage = targetImage;
|
||||
|
||||
@ -579,7 +576,7 @@ public class Img implements Serializable {
|
||||
* @since 5.4.1
|
||||
*/
|
||||
public Img stroke(Color color, Stroke stroke){
|
||||
final BufferedImage image = ImgUtil.toBufferedImage(getValidSrcImg());
|
||||
final BufferedImage image = ImgUtil.toBufferedImage(getValidSrcImg(), this.targetImageType);
|
||||
int width = image.getWidth(null);
|
||||
int height = image.getHeight(null);
|
||||
Graphics2D g = image.createGraphics();
|
||||
@ -717,6 +714,16 @@ public class Img implements Serializable {
|
||||
return ObjectUtil.defaultIfNull(this.targetImage, this.srcImage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取有效的源{@link BufferedImage}图片,首先检查上一次处理的结果图片,如无则使用用户传入的源图片
|
||||
*
|
||||
* @return 有效的源图片
|
||||
* @since 5.7.8
|
||||
*/
|
||||
private BufferedImage getValidSrcBufferedImg() {
|
||||
return ImgUtil.toBufferedImage(getValidSrcImg(), this.targetImageType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修正矩形框位置,如果{@link Img#setPositionBaseCentre(boolean)} 设为{@code true},则坐标修正为基于图形中心,否则基于左上角
|
||||
*
|
||||
|
@ -30,10 +30,14 @@ import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BufferedImageOp;
|
||||
import java.awt.image.ColorConvertOp;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
@ -451,9 +455,9 @@ public class ImgUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 图像切割(指定切片的行数和列数)
|
||||
* 图像切割(指定切片的行数和列数),默认RGB模式
|
||||
*
|
||||
* @param srcImage 源图像
|
||||
* @param srcImage 源图像,如果非{@link BufferedImage},则默认使用RGB模式
|
||||
* @param destDir 切片目标文件夹
|
||||
* @param rows 目标切片行数。默认2,必须是范围 [1, 20] 之内
|
||||
* @param cols 目标切片列数。默认2,必须是范围 [1, 20] 之内
|
||||
@ -1167,8 +1171,8 @@ public class ImgUtil {
|
||||
*/
|
||||
public static BufferedImage toBufferedImage(Image image, String imageType) {
|
||||
final int type = IMAGE_TYPE_PNG.equalsIgnoreCase(imageType)
|
||||
? BufferedImage.TYPE_INT_ARGB
|
||||
: BufferedImage.TYPE_INT_RGB;
|
||||
? BufferedImage.TYPE_INT_ARGB
|
||||
: BufferedImage.TYPE_INT_RGB;
|
||||
return toBufferedImage(image, type);
|
||||
}
|
||||
|
||||
@ -1652,7 +1656,7 @@ public class ImgUtil {
|
||||
* @return {@link Image}
|
||||
* @since 5.5.8
|
||||
*/
|
||||
public static Image getImage(URL url){
|
||||
public static Image getImage(URL url) {
|
||||
return Toolkit.getDefaultToolkit().getImage(url);
|
||||
}
|
||||
|
||||
@ -2148,4 +2152,42 @@ public class ImgUtil {
|
||||
public static BufferedImage backgroundRemoval(ByteArrayOutputStream outputStream, Color override, int tolerance) {
|
||||
return BackgroundRemoval.backgroundRemoval(outputStream, override, tolerance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片颜色转换<br>
|
||||
* 可以使用灰度 (gray)等
|
||||
*
|
||||
* @param colorSpace 颜色模式,如灰度等
|
||||
* @param image 被转换的图片
|
||||
* @return 转换后的图片
|
||||
* @since 5.7.8
|
||||
*/
|
||||
public static BufferedImage colorConvert(ColorSpace colorSpace, BufferedImage image) {
|
||||
return filter(new ColorConvertOp(colorSpace, null), image);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换图片<br>
|
||||
* 可以使用一系列平移 (translation)、缩放 (scale)、翻转 (flip)、旋转 (rotation) 和错切 (shear) 来构造仿射变换。
|
||||
*
|
||||
* @param xform 2D仿射变换,它执行从 2D 坐标到其他 2D 坐标的线性映射,保留了线的“直线性”和“平行性”。
|
||||
* @param image 被转换的图片
|
||||
* @return 转换后的图片
|
||||
* @since 5.7.8
|
||||
*/
|
||||
public static BufferedImage transform(AffineTransform xform, BufferedImage image) {
|
||||
return filter(new AffineTransformOp(xform, null), image);
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片过滤转换
|
||||
*
|
||||
* @param op 过滤操作实现,如二维转换可传入{@link AffineTransformOp}
|
||||
* @param image 原始图片
|
||||
* @return 过滤后的图片
|
||||
* @since 5.7.8
|
||||
*/
|
||||
public static BufferedImage filter(BufferedImageOp op, BufferedImage image) {
|
||||
return op.filter(image, null);
|
||||
}
|
||||
}
|
||||
|
@ -10,19 +10,16 @@ import cn.hutool.extra.tokenizer.engine.mmseg.MmsegEngine;
|
||||
import cn.hutool.extra.tokenizer.engine.mynlp.MynlpEngine;
|
||||
import cn.hutool.extra.tokenizer.engine.word.WordEngine;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* 模板引擎单元测试
|
||||
*
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class TokenizerUtilTest {
|
||||
|
||||
|
||||
String text = "这两个方法的区别在于返回值";
|
||||
|
||||
@Test
|
||||
@ -32,73 +29,71 @@ public class TokenizerUtilTest {
|
||||
Result result = engine.parse(text);
|
||||
checkResult(result);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void hanlpTest() {
|
||||
TokenizerEngine engine = new HanLPEngine();
|
||||
Result result = engine.parse(text);
|
||||
String resultStr = IterUtil.join((Iterator<Word>)result, " ");
|
||||
String resultStr = IterUtil.join(result, " ");
|
||||
Assert.assertEquals("这 两 个 方法 的 区别 在于 返回 值", resultStr);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void ikAnalyzerTest() {
|
||||
TokenizerEngine engine = new IKAnalyzerEngine();
|
||||
Result result = engine.parse(text);
|
||||
String resultStr = IterUtil.join((Iterator<Word>)result, " ");
|
||||
String resultStr = IterUtil.join(result, " ");
|
||||
Assert.assertEquals("这两个 方法 的 区别 在于 返回值", resultStr);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void jcsegTest() {
|
||||
TokenizerEngine engine = new JcsegEngine();
|
||||
Result result = engine.parse(text);
|
||||
checkResult(result);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void jiebaTest() {
|
||||
TokenizerEngine engine = new JiebaEngine();
|
||||
Result result = engine.parse(text);
|
||||
String resultStr = IterUtil.join((Iterator<Word>)result, " ");
|
||||
String resultStr = IterUtil.join(result, " ");
|
||||
Assert.assertEquals("这 两个 方法 的 区别 在于 返回值", resultStr);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void mmsegTest() {
|
||||
TokenizerEngine engine = new MmsegEngine();
|
||||
Result result = engine.parse(text);
|
||||
checkResult(result);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void smartcnTest() {
|
||||
TokenizerEngine engine = new SmartcnEngine();
|
||||
Result result = engine.parse(text);
|
||||
String resultStr = IterUtil.join((Iterator<Word>)result, " ");
|
||||
String resultStr = IterUtil.join(result, " ");
|
||||
Assert.assertEquals("这 两 个 方法 的 区别 在于 返回 值", resultStr);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void wordTest() {
|
||||
TokenizerEngine engine = new WordEngine();
|
||||
Result result = engine.parse(text);
|
||||
String resultStr = IterUtil.join((Iterator<Word>)result, " ");
|
||||
String resultStr = IterUtil.join(result, " ");
|
||||
Assert.assertEquals("这两个 方法 的 区别 在于 返回值", resultStr);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void mynlpTest() {
|
||||
// 此单元测试需要JDK8,默认忽略
|
||||
TokenizerEngine engine = new MynlpEngine();
|
||||
Result result = engine.parse(text);
|
||||
String resultStr = IterUtil.join((Iterator<Word>)result, " ");
|
||||
String resultStr = IterUtil.join(result, " ");
|
||||
Assert.assertEquals("这 两个 方法 的 区别 在于 返回 值", resultStr);
|
||||
}
|
||||
|
||||
|
||||
private void checkResult(Result result) {
|
||||
String resultStr = IterUtil.join((Iterator<Word>)result, " ");
|
||||
String resultStr = IterUtil.join(result, " ");
|
||||
Assert.assertEquals("这 两个 方法 的 区别 在于 返回 值", resultStr);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user