mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
add methods
This commit is contained in:
parent
c1fc2cfc85
commit
d890d60b14
@ -3,7 +3,7 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.8.0.M3 (2022-04-12)
|
||||
# 5.8.0.M3 (2022-04-13)
|
||||
|
||||
### ❌不兼容特性
|
||||
* 【core 】 StreamProgress#progress方法参数变更为2个(pr#594@Gitee)
|
||||
@ -17,6 +17,7 @@
|
||||
* 【core 】 Snowflake支持sequence使用随机数(issue#I51EJY@Gitee)
|
||||
* 【core 】 JarClassLoader增加构造(pr#593@Gitee)
|
||||
* 【core 】 增加Pid,以便获取单例pid
|
||||
* 【core 】 Img增加全覆盖水印pressTextFull(pr#595@Gitee)
|
||||
|
||||
### 🐞Bug修复
|
||||
* 【core 】 修复UserAgentUtil识别Linux出错(issue#I50YGY@Gitee)
|
||||
|
@ -12,12 +12,24 @@ import cn.hutool.core.util.StrUtil;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.awt.image.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.CropImageFilter;
|
||||
import java.awt.image.ImageFilter;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@ -249,8 +261,8 @@ public class Img implements Serializable {
|
||||
* 缩放图像(按长宽缩放)<br>
|
||||
* 注意:目标长宽与原图不成比例会变形
|
||||
*
|
||||
* @param width 目标宽度
|
||||
* @param height 目标高度
|
||||
* @param width 目标宽度
|
||||
* @param height 目标高度
|
||||
* @param scaleType 缩放类型,可选{@link Image#SCALE_SMOOTH}平滑模式或{@link Image#SCALE_DEFAULT}默认模式
|
||||
* @return this
|
||||
* @since 5.7.18
|
||||
@ -435,7 +447,8 @@ public class Img implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 给图片添加文字水印
|
||||
* 给图片添加文字水印<br>
|
||||
* 此方法只在给定位置写出一个水印字符串
|
||||
*
|
||||
* @param pressText 水印文字
|
||||
* @param color 水印的字体颜色
|
||||
@ -446,13 +459,29 @@ public class Img implements Serializable {
|
||||
* @return 处理后的图像
|
||||
*/
|
||||
public Img pressText(String pressText, Color color, Font font, int x, int y, float alpha) {
|
||||
return pressText(pressText, color, font, new Point(x, y), alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给图片添加文字水印<br>
|
||||
* 此方法只在给定位置写出一个水印字符串
|
||||
*
|
||||
* @param pressText 水印文字
|
||||
* @param color 水印的字体颜色
|
||||
* @param font {@link Font} 字体相关信息
|
||||
* @param point 绘制字符串的位置坐标
|
||||
* @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
|
||||
* @return 处理后的图像
|
||||
*/
|
||||
public Img pressText(String pressText, Color color, Font font, Point point, float alpha) {
|
||||
final BufferedImage targetImage = ImgUtil.toBufferedImage(getValidSrcImg(), this.targetImageType);
|
||||
final Graphics2D g = targetImage.createGraphics();
|
||||
|
||||
if (null == font) {
|
||||
// 默认字体
|
||||
font = FontUtil.createSansSerifFont((int) (targetImage.getHeight() * 0.75));
|
||||
}
|
||||
|
||||
final Graphics2D g = targetImage.createGraphics();
|
||||
// 透明度
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
|
||||
|
||||
@ -460,11 +489,10 @@ public class Img implements Serializable {
|
||||
if (positionBaseCentre) {
|
||||
// 基于中心绘制
|
||||
GraphicsUtil.drawString(g, pressText, font, color,
|
||||
new Rectangle(x, y, targetImage.getWidth(), targetImage.getHeight()));
|
||||
new Rectangle(point.x, point.y, targetImage.getWidth(), targetImage.getHeight()));
|
||||
} else {
|
||||
// 基于左上角绘制
|
||||
GraphicsUtil.drawString(g, pressText, font, color,
|
||||
new Point(x, y));
|
||||
GraphicsUtil.drawString(g, pressText, font, color, point);
|
||||
}
|
||||
|
||||
// 收笔
|
||||
@ -478,73 +506,56 @@ public class Img implements Serializable {
|
||||
/**
|
||||
* 给图片添加全屏文字水印
|
||||
*
|
||||
* @param pressText 水印文字
|
||||
* @param color 水印的字体颜色
|
||||
* @param font {@link Font} 字体相关信息
|
||||
* @param degree 旋转角度,(单位:弧度),以圆点(0,0)为圆心,正代表顺时针,负代表逆时针
|
||||
* @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
|
||||
* @param pressText 水印文字,文件间的间隔使用尾部添加空格方式实现
|
||||
* @param color 水印的字体颜色
|
||||
* @param font {@link Font} 字体相关信息
|
||||
* @param lineHeight 行高
|
||||
* @param degree 旋转角度,(单位:弧度),以圆点(0,0)为圆心,正代表顺时针,负代表逆时针
|
||||
* @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
|
||||
* @return 处理后的图像
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public Img pressTextFullScreen(String pressText, Color color, Font font, int degree, float alpha) {
|
||||
public Img pressTextFull(String pressText, Color color, Font font, int lineHeight, int degree, float alpha) {
|
||||
final BufferedImage targetImage = ImgUtil.toBufferedImage(getValidSrcImg(), this.targetImageType);
|
||||
final int targetwidth = targetImage.getWidth();
|
||||
final int targetheight = targetImage.getHeight();
|
||||
return pressImage(createFullScreenPressImage(targetwidth, targetheight, pressText, color, font, degree, alpha).getImg(), 0, 0, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* 水印文字生成全屏水印图片
|
||||
*
|
||||
* @param targetwidth 水印图片宽
|
||||
* @param targetheight 水印图片高
|
||||
* @param pressText 水印字符串
|
||||
* @param color 水印的字体颜色
|
||||
* @param font {@link Font} 字体相关信息
|
||||
* @param degree 旋转角度,(单位:弧度),以圆点(0,0)为圆心,正代表顺时针,负代表逆时针
|
||||
* @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
|
||||
* @return Img
|
||||
*/
|
||||
private static Img createFullScreenPressImage(int targetwidth, int targetheight, String pressText, Color color, Font font, int degree, float alpha) {
|
||||
ColorModel cm = ColorModel.getRGBdefault();
|
||||
WritableRaster wr = cm.createCompatibleWritableRaster(targetwidth, targetheight);
|
||||
BufferedImage pressImg = new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
|
||||
if (null == font) {
|
||||
// 默认字体
|
||||
font = FontUtil.createSansSerifFont((int) (targetImage.getHeight() * 0.75));
|
||||
}
|
||||
final int targetHeight = targetImage.getHeight();
|
||||
final int targetWidth = targetImage.getWidth();
|
||||
|
||||
// 创建画笔,并设置透明度和角度
|
||||
final Graphics2D g = targetImage.createGraphics();
|
||||
g.setColor(color);
|
||||
// 基于图片中心旋转
|
||||
g.rotate(Math.toRadians(degree), targetWidth >> 1, targetHeight >> 1);
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
|
||||
|
||||
// 水印图片放大倍数
|
||||
final float scale = 2;
|
||||
font = font.deriveFont(font.getSize() / scale);
|
||||
final Graphics2D g = pressImg.createGraphics();
|
||||
//获取字符串本身的长宽
|
||||
Dimension dimension;
|
||||
try {
|
||||
// 3字间隔
|
||||
dimension = FontUtil.getDimension(g.getFontMetrics(font), pressText + " ");
|
||||
dimension = FontUtil.getDimension(g.getFontMetrics(font), pressText);
|
||||
} catch (Exception e) {
|
||||
// 此处报告bug某些情况下会抛出IndexOutOfBoundsException,在此做容错处理
|
||||
dimension = new Dimension(targetwidth / 3, targetheight / 3);
|
||||
dimension = new Dimension(targetWidth / 3, targetHeight / 3);
|
||||
}
|
||||
|
||||
// 3倍间宽 间隔
|
||||
final int intervalHeight = dimension.height * 4;
|
||||
// 循环写
|
||||
int y = dimension.height;
|
||||
while (y < targetheight) {
|
||||
int x = 0;
|
||||
while (x < targetwidth) {
|
||||
|
||||
GraphicsUtil.drawString(g, pressText, font, color,
|
||||
new Point(x, y));
|
||||
final int intervalHeight = dimension.height * lineHeight;
|
||||
// 在画笔按照画布中心旋转后,达到45度时,上下左右会出现空白区,此处各延申长款的1.5倍实现全覆盖
|
||||
int y = -targetHeight >> 1;
|
||||
while (y < targetHeight * 1.5) {
|
||||
int x = -targetWidth >> 1;
|
||||
while (x < targetWidth * 1.5) {
|
||||
GraphicsUtil.drawString(g, pressText, font, color, new Point(x, y));
|
||||
x += dimension.width;
|
||||
}
|
||||
y += intervalHeight;
|
||||
}
|
||||
g.dispose();
|
||||
// 水印图片旋转,放大,剪切
|
||||
return Img.from(pressImg)
|
||||
.rotate(degree)
|
||||
.scale(scale)
|
||||
.cut(new Rectangle(0, 0, targetwidth, targetheight));
|
||||
}
|
||||
|
||||
this.targetImage = targetImage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给图片添加图片水印
|
||||
@ -629,30 +640,30 @@ public class Img implements Serializable {
|
||||
* @return this
|
||||
* @since 5.4.1
|
||||
*/
|
||||
public Img stroke(Color color, float width){
|
||||
public Img stroke(Color color, float width) {
|
||||
return stroke(color, new BasicStroke(width));
|
||||
}
|
||||
|
||||
/**
|
||||
* 描边,此方法为向内描边,会覆盖图片相应的位置
|
||||
*
|
||||
* @param color 描边颜色,默认黑色
|
||||
* @param color 描边颜色,默认黑色
|
||||
* @param stroke 描边属性,包括粗细、线条类型等,见{@link BasicStroke}
|
||||
* @return this
|
||||
* @since 5.4.1
|
||||
*/
|
||||
public Img stroke(Color color, Stroke stroke){
|
||||
public Img stroke(Color color, Stroke stroke) {
|
||||
final BufferedImage image = ImgUtil.toBufferedImage(getValidSrcImg(), this.targetImageType);
|
||||
int width = image.getWidth(null);
|
||||
int height = image.getHeight(null);
|
||||
Graphics2D g = image.createGraphics();
|
||||
|
||||
g.setColor(ObjectUtil.defaultIfNull(color, Color.BLACK));
|
||||
if(null != stroke){
|
||||
if (null != stroke) {
|
||||
g.setStroke(stroke);
|
||||
}
|
||||
|
||||
g.drawRect(0, 0, width -1 , height - 1);
|
||||
g.drawRect(0, 0, width - 1, height - 1);
|
||||
|
||||
g.dispose();
|
||||
this.targetImage = image;
|
||||
|
@ -55,12 +55,14 @@ public class ImgTest {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testPressTextFullScreen() {
|
||||
Img.from(FileUtil.file("d:/test/2.jpg"))
|
||||
.pressTextFullScreen("版权所有 仿冒必究", Color.LIGHT_GRAY,
|
||||
new Font("微软雅黑", Font.BOLD, 100),
|
||||
-30,
|
||||
1f)
|
||||
public void pressTextFullScreenTest() {
|
||||
Img.from(FileUtil.file("d:/test/1435859438434136064.jpg"))
|
||||
.setTargetImageType(ImgUtil.IMAGE_TYPE_PNG)
|
||||
.pressTextFull("版权所有 ", Color.LIGHT_GRAY,
|
||||
new Font("黑体", Font.PLAIN, 30),
|
||||
4,
|
||||
30,
|
||||
0.8f)
|
||||
.write(FileUtil.file("d:/test/2_result.png"));
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user