工具类
需要先引用依赖
<!--图像处理-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.17</version>
</dependency>
绘制工具类,主要用于输出字符串,也可以自行添加更多功能进行增强。
package com.test.draw;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Coordinate;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 绘制图像
*
* @author zhangxuetu
* @date 2022-09-21
*/
public class DrawUtil {
private BufferedImage image;
private Graphics2D graphics2D;
private Rectangle size;
/**
* 构造方法
*/
private DrawUtil(BufferedImage image, Rectangle size, Color color) {
this.image = image;
this.size = size;
resetImage(image, false);
full(color);
}
private DrawUtil(BufferedImage image, Rectangle size) {
this(image, size, Color.WHITE);
this.graphics2D.setColor(Color.BLACK);
}
/**
* 获取实例
*
* @param size 图像大小
* @param backgroundColor 背景颜色,默认颜色为黑色
*/
public static DrawUtil getInstance(Rectangle size, Color backgroundColor) {
BufferedImage image = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
return new DrawUtil(image, size, backgroundColor);
}
public static DrawUtil getInstance(int width, int height, Color backgroundColor) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
return new DrawUtil(image, new Rectangle(width, height), backgroundColor);
}
public static DrawUtil getInstance(int width, int height) {
final DrawUtil instance = getInstance(width, height, Color.WHITE);
instance.getGraphics2D().setColor(Color.BLACK);
return instance;
}
public static DrawUtil getInstance(Rectangle rectangle) {
return getInstance(rectangle.width, rectangle.height);
}
/**
* 获取实例
*
* @param image 以这个图片作为绘制对象
* @param backgroundColor 背景颜色,默认颜色为黑色
* @return 返回这个图像的操作实例
*/
public static DrawUtil getInstance(BufferedImage image, Color backgroundColor) {
return new DrawUtil(image, new Rectangle(image.getWidth(), image.getHeight()), backgroundColor);
}
public static DrawUtil getInstance(BufferedImage image) {
return new DrawUtil(image, new Rectangle(image.getWidth(), image.getHeight()));
}
public BufferedImage getImage() {
return image;
}
public Graphics2D getGraphics2D() {
return graphics2D;
}
public Rectangle getSize() {
return size;
}
/**
* 填充整个画布的颜色
*
* @param color 整个画布的颜色
*/
public DrawUtil full(Color color) {
// 先用白色画笔填充整张图片的颜色,也就是设置背景
graphics2D.setColor(color);
graphics2D.fillRect(0, 0, size.width, size.height);
return this;
}
public DrawUtil setColor(Color color) {
graphics2D.setColor(color);
return this;
}
public DrawUtil setFont(Font font) {
graphics2D.setFont(font);
return this;
}
public DrawUtil setStroke(Stroke stroke) {
graphics2D.setStroke(stroke);
return this;
}
/**
* 重新设置大小
*
* @param newSize 新的大小
*/
public void resize(Rectangle newSize) {
this.size = newSize;
resize(image, newSize.width, newSize.height);
}
public void resize(BufferedImage image, int width, int height) {
final BufferedImage newImage = image.getSubimage(0, 0, width, height);
resetImage(newImage, true);
}
/**
* 绘制线条
*
* @param color 线条颜色
* @param width 线条粗细
* @param startPoint 起始点
* @param endPoint 终点
*/
public DrawUtil drawLine(Color color, int width, Point startPoint, Point endPoint) {
BasicStroke bs = new BasicStroke(width);
graphics2D.setStroke(bs);
graphics2D.setColor(color);
for (int i = 0; i < width; i++) {
graphics2D.drawLine(startPoint.x + i, startPoint.y, endPoint.x, endPoint.y);
}
return this;
}
public DrawUtil drawLine(int width, Point startPoint, Point endPoint) {
return drawLine(graphics2D.getColor(), width, startPoint, endPoint);
}
/**
* 偏移点位置
*
* @param point 要偏移的点
* @param offset 追加的偏移值
*/
public DrawUtil offset(Point point, Point offset) {
return offset(point, offset.x, offset.y);
}
public DrawUtil offset(Point point, int x, int y) {
point.x += x;
point.y += y;
return this;
}
/**
* 偏移到字体高度的位置下面
*
* @param point 要偏移的点
*/
public DrawUtil offsetFontHeight(Point point) {
return offset(point, 0, getFontHeight());
}
/**
* 绘制文字
*/
public DrawUtil drawString(String text, Color color, Font font, Point point) {
// 绘制
graphics2D.setColor(color);
graphics2D.setFont(font);
graphics2D.drawString(text, point.x, point.y);
return this;
}
public DrawUtil drawString(String text, Point point) {
return drawString(text, graphics2D.getColor(), graphics2D.getFont(), point);
}
/**
* 绘制多行文字,会对文字自动换行
*
* @param text 要绘制的文字
* @param maxWidth 每行文字最大宽度
*/
public DrawUtil drawMultiRowString(String text, Color color, Font font, Point point, int maxWidth, int lineSpace) {
final List<String> stringList = textWrap(font, text, maxWidth);
return drawMultiRowString(stringList, color, font, point, lineSpace);
}
public DrawUtil drawMultiRowString(List<String> stringList, Color color, Font font, Point point, int lineSpace) {
return drawMultiRowString(stringList.toArray(new String[0]), color, font, point, lineSpace);
}
/**
* 获取这些文字的整体宽度
*
* @param font 字体
* @param text 字符串内容
*/
public int getStringWidth(Font font, String text) {
final FontMetrics fontMetrics = graphics2D.getFontMetrics(font);
return fontMetrics.stringWidth(text);
}
/**
* 获取当前的字体的这些字符串的宽度
*
* @param text 字符串内容
*/
public int getStringWidth(String text) {
final Font font = graphics2D.getFont();
return getStringWidth(font, text);
}
/**
* 绘制多行文字。绘制完最终 point 的 y 值会偏移一行文字和 lineSpace 的值,有时可能需要自行减去
*
* @param strings 字符串列表
* @param color 字体颜色
* @param font 字体
* @param point 开始绘制的位置
* @param lineSpace 每行字的间隔空间
*/
public DrawUtil drawMultiRowString(String[] strings, Color color, Font font, Point point, int lineSpace) {
setFont(font);
int lineHeight = getFontHeight() + lineSpace;
for (String text : strings) {
drawString(text, color, font, point);
point.y += lineHeight;
}
return this;
}
/**
* 释放当前绘制的图像,表示已经绘制完成
*
* @param finish 是否已经绘制全部完成
*/
public void dispose(boolean finish) {
graphics2D.dispose();
if (!finish) {
graphics2D = image.createGraphics();
} else {
graphics2D = null;
}
}
public void dispose() {
dispose(true);
}
/**
* 保存图片
*
* @param path 图片路径
* @return 返回是否保存成功
*/
public boolean saveImage(String path) {
try {
File outFile = new File(path);
// 输出jpg图片
ImageIO.write(image, "jpg", outFile);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* 文字换行拆分,根据计算将字符串拆分成多个,进行换行
*
* @param font 字体
* @param text 字符串内容
* @param maxWidth 最大宽度
* @return 返回换行后的字符串列表
*/
public List<String> textWrap(Font font, String text, int maxWidth) {
FontMetrics fm = graphics2D.getFontMetrics(font);
// 可拆分的行
List<String> list = new ArrayList<>();
int beginIndex = 0;
String tempString;
for (int i = 0; i < text.length(); i++) {
tempString = text.substring(beginIndex, i);
if (fm.stringWidth(tempString) >= maxWidth) {
list.add(text.substring(beginIndex, i));
beginIndex = i;
}
}
if (beginIndex < text.length()) {
list.add(text.substring(beginIndex));
}
return list;
}
/**
* 获取字符串在宽度中的 x 位置
*
* @param width 宽度
* @param font 字体
* @param text 字符串
*/
public int getHorizontalCenterPos(int width, Font font, String text) {
final int stringWidth = getStringWidth(font, text);
return (width - stringWidth) / 2;
}
/**
* 添加水印
*/
public boolean watermark(Point position, BufferedImage image) {
return watermark(position, image, 1.0F);
}
public boolean watermark(int x, int y, BufferedImage image) {
return watermark(new Point(x, y), image);
}
/**
* 添加水印
*
* @param position 添加到的位置
*/
public boolean watermark(Point position, BufferedImage image, float transparency) {
return watermark(new Coordinate(position.x, position.y), image, transparency, 1.0F);
}
/**
* 添加水印
*
* @param scale 缩放水印大小
*/
public boolean watermark(Point position, BufferedImage image, float transparency, float scale) {
return watermark(new Coordinate(position.x, position.y), image, transparency, scale);
}
/**
* 添加水印
*
* @param position 添加到的位置
* @param image 水印图片
* @param transparency 透明度
* @param scale 缩放
*/
public boolean watermark(Coordinate position, BufferedImage image, float transparency, float scale) {
try {
if (scale != 1.0F) {
image = Thumbnails.of(image).scale(scale).asBufferedImage();
}
// 对图片进行添加水印
final BufferedImage newImage = Thumbnails.of(this.image)
.size(size.width, size.height)
.watermark(position, image, transparency)
.asBufferedImage();
// 重新设置 Image
resetImage(newImage, true);
return true;
} catch (IOException e) {
// throw new RuntimeException(e);
e.printStackTrace();
return false;
}
}
/**
* 重新设置 Image
*
* @param newImage 新的 BufferedImage
* @param keepPreviousGraphicsProperty 保持之前的 Graphics2D 的一些属性
*/
public DrawUtil resetImage(BufferedImage newImage, boolean keepPreviousGraphicsProperty) {
// 之前的属性
Font previousFont = null;
Color previousColor = null;
Stroke previousStroke = null;
if (keepPreviousGraphicsProperty) {
previousFont = graphics2D.getFont();
previousColor = graphics2D.getColor();
previousStroke = graphics2D.getStroke();
}
this.image = newImage;
this.graphics2D = this.image.createGraphics();
this.graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (keepPreviousGraphicsProperty) {
this.graphics2D.setFont(previousFont);
this.graphics2D.setColor(previousColor);
this.graphics2D.setStroke(previousStroke);
}
return this;
}
/**
* 获取字体高度
*/
public int getFontHeight() {
final Font font = graphics2D.getFont();
return getFontHeight(font);
}
public int getFontHeight(Font font) {
final FontMetrics fontMetrics = graphics2D.getFontMetrics(font);
return fontMetrics.getHeight();
}
}
测试代码
import java.awt.*;
public class Main {
public static void main(String[] args) {
// 开始绘制的点的位置
Point drawPoint = new Point(10, 10);
// 创建 200x200 大小的图片
final DrawUtil drawUtil = DrawUtil.getInstance(200, 200);
drawUtil.setFont(new Font("宋体", Font.PLAIN, 20))
.offsetFontHeight(drawPoint)
.drawString("text", drawPoint)
.offset(drawPoint, new Point(0, 10))
.drawLine(1, new Point(10, drawPoint.y), new Point(190, drawPoint.y))
.offsetFontHeight(drawPoint)
.drawString("abzxc 绘制文字", drawPoint)
.dispose();
boolean result = drawUtil.saveImage("C:\\Users\\Administrator\\Desktop\\test.jpg");
System.out.println(result ? "保存成功" : "保存失败");
}
}
输出图片如下: