一个功能简单的图片工具类
Posted justry_deng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个功能简单的图片工具类相关的知识,希望对你有一定的参考价值。
功能说明&演示
1. 文字转换为图片
- 代码示例(更多用法见重载方法说明)
/** * 文字转换为图片 demo */ public static void main(String[] args) throws Exception BufferedImage bufferedImage = ImgUtil.strConvertToImg( Lists.newArrayList( "用户:邓沙利文", "性别:男", "年龄:18岁18天", "爱好:摆烂", "座右铭:我是一只小小小小鸟~嗷!嗷!" ), new Font("幼圆", Font.PLAIN, 20), new Color(255, 0, 0)); System.err.println( ImageIO.write(bufferedImage, "PNG", new File("E:\\\\360MoveData\\\\Users\\\\邓沙利文\\\\Desktop\\\\abc.png")) );
- 效果图(图片其实是透明背景的;因为我这里是编辑打开,所以显示的是白色)
2. 生成指定大小透明背景的图片,并设置文字
- 代码示例(更多用法见重载方法说明)
BufferedImage bufferedImage = ImgUtil.generateImgWithStr( Lists.newArrayList( "用户:邓沙利文", "性别:男", "年龄:18岁18天", "爱好:摆烂", "座右铭:我是一只小小小小鸟~嗷!嗷!" ), // 指定要生成的图片大小 500, 500, // 指定字体及颜色(不指定的话, 默认: 微软雅黑 白色); 当字体大小<=0时,将自动推算字体大小,使其布满图片 new Font("幼圆", Font.PLAIN, -1), new Color(255, 0, 0)); System.err.println( ImageIO.write(bufferedImage, "PNG", new File("E:\\\\360MoveData\\\\Users\\\\邓沙利文\\\\Desktop\\\\abc.png")) );
- 效果图(图片其实是透明背景的;因为我这里是编辑打开,所以显示的是白色)
3. 添加水印
- 代码示例(更多用法见重载方法说明)
// 可设置字体颜色等,详见重载方法说明; 当字体大小<=0时,将自动推算字体大小,使其布满图片 BufferedImage bufferedImage = ImgUtil.addWatermark( ImageIO.read(new File("E:\\\\360MoveData\\\\Users\\\\邓沙利文\\\\Desktop\\\\熊猫.jpg")) , Lists.newArrayList( "用户:邓沙利文", "性别:男", "年龄:18岁18天", "爱好:摆烂", "座右铭:我是一只小小小小鸟~嗷!嗷!" )); System.err.println( ImageIO.write(bufferedImage, "PNG", new File("E:\\\\360MoveData\\\\Users\\\\邓沙利文\\\\Desktop\\\\abc.png")) );
- 效果图(图片其实是透明背景的;因为我这里是编辑打开,所以显示的是白色)
使用方式
方式一:直接引入common-ds依赖
common-ds:一个工具类开源包
common-spring:一个spring工具类开源包,集成了common-ds
引入以下依赖后,调用ImgUtil
的静态方法即可
<dependency>
<groupId>com.idea-aedi</groupId>
<artifactId>common-ds</artifactId>
<version>2100.5.0</version>
</dependency>
方式二:直接将工具类源码复制到项目中
ImgUtil工具类
import org.apache.commons.lang3.tuple.Triple;
import javax.annotation.Nullable;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* 图片工具类
* <br/>
* 需要相关依赖:
* <br/>
* <dependency>
* <groupId>org.apache.commons</groupId>
* <artifactId>commons-lang3</artifactId>
* <version>3.12.0</version>
* </dependency>
*
* @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
* src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
* @since 2100.4.6
*/
public class ImgUtil
/**
* 中文&中文标点正则
* <br />
* [\\u4e00-\\u9fa5]是中文,其余的是中文标点符号
*/
private static final Pattern CHINESE_PATTERN = Pattern.compile("[\\u4e00-\\u9fa5]|[\\uFF01]|[\\uFF0C-\\uFF0E]|[\\uFF1A-\\uFF1B"
+ "]|[\\uFF1F]|[\\uFF08-\\uFF09]|[\\u3001-\\u3002]|[\\u3010-\\u3011]|[\\u201C-\\u201D]|[\\u2013-\\u2014]|[\\u2018"
+ "-\\u2019]|[\\u2026]|[\\u3008-\\u300F]|[\\u3014-\\u3015]");
/** 行间距(px) */
public static final int DEFAULT_LINE_SPACING = 5;
/** 左下角 */
public static final int POSITION_BOTTOM_LEFT = 1;
/** 右下角 */
public static final int POSITION_BOTTOM_RIGHT = 2;
/** 左上角 */
public static final int POSITION_TOP_LEFT = 3;
/** 右上角 */
public static final int POSITION_TOP_RIGHT = 4;
/**
* 生成带有文字的透明背景的图片 <br/> 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
*
* @return 图片
* @see ImgUtil#generateImgWithStr(List, int, int, Font, Color, int, int)
*/
public static BufferedImage generateImgWithStr(List<String> contentLines, int imgWidth, int imgHeight)
return generateImgWithStr(contentLines, imgWidth, imgHeight, new Font("微软雅黑", Font.PLAIN, 0),
new Color(255, 255, 255), DEFAULT_LINE_SPACING, POSITION_BOTTOM_LEFT);
/**
* 生成带有文字的透明背景的图片 <br/> 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
*
* @return 图片
* @see ImgUtil#generateImgWithStr(List, int, int, Font, Color, int, int)
*/
public static BufferedImage generateImgWithStr(List<String> contentLines, int imgWidth, int imgHeight,
Font font, Color fontColor)
return generateImgWithStr(contentLines, imgWidth, imgHeight, font, fontColor, DEFAULT_LINE_SPACING,
POSITION_BOTTOM_LEFT);
/**
* 生成带有文字的透明背景的图片 <br/> 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
*
* @param contentLines
* 文本
* @param imgWidth
* 图片宽
* @param imgHeight
* 图片高
* @param font
* 字
* @param fontColor
* 字体颜色
* @param lineSpacing
* 行间距(单位: 像素)
* @param contentPosition
* 文字位置 <br />
* @link ImgUtil#POSITION_BOTTOM_LEFT
* @link ImgUtil#POSITION_BOTTOM_RIGHT
* @link ImgUtil#POSITION_TOP_LEFT
* @link ImgUtil#POSITION_TOP_RIGHT
*
* @return 图片
*/
public static BufferedImage generateImgWithStr(List<String> contentLines, int imgWidth, int imgHeight,
Font font, Color fontColor, int lineSpacing, int contentPosition)
if (imgWidth <= 0 || imgHeight <= 0)
throw new IllegalArgumentException("imgWidth or imgHeight cannot less than 0 or equal 0.");
// step1. 计算文本的行数以及最大长度
Triple<Integer, Integer, Integer> triple = computeLineCountAndMaxLength(null, contentLines, font);
int lineCount = triple.getLeft();
int maxLength;
// step2. 计算字体大小(当字体大小<=0时,将根据图片大小自动计算字体的大小)
int fontSize = font.getSize();
if (fontSizeIsIllegal(fontSize))
//noinspection PointlessArithmeticExpression
double computeHeight = imgHeight * 1 - (lineCount - 1) * lineSpacing;
//noinspection PointlessArithmeticExpression
double computeWidth = imgWidth * 1;
if (computeHeight <= 0 || computeWidth <= 0)
throw new IllegalArgumentException("computeHeight or computeWidth is illegal.");
Integer maxLengthLineCharCount = triple.getRight();
Objects.requireNonNull(maxLengthLineCharCount, "maxLengthLineCharCount should not be null while fontSize "
+ "<= 0.");
fontSize = (int) Math.min(computeHeight / lineCount, computeWidth / maxLengthLineCharCount);
// 文本的最大长度(像素)
maxLength = fontSize * maxLengthLineCharCount;
else
Integer middle = triple.getMiddle();
Objects.requireNonNull(middle, "middle should not be null while fontSize > 0.");
// 文本的最大长度(像素)
maxLength = middle;
// step3. 创建 图形1(图层1) 作为 底色
BufferedImage bufferedImage = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = bufferedImage.createGraphics();
graphics.clearRect(0, 0, imgWidth, imgHeight);
bufferedImage = graphics.getDeviceConfiguration().createCompatibleImage(imgWidth, imgHeight,
Transparency.TRANSLUCENT);
graphics.dispose();
// step4. 创建 图形2(图层2) 勾画文本
graphics = bufferedImage.createGraphics();
graphics.setColor(fontColor);
graphics.setFont(new Font(font.getName(), font.getStyle(), fontSize));
// x向右为正, y向下为正
int startX;
// 这里发现:Y坐标, 还需要调整(fontSize / 6)后,文字才能正好显示
int startY;
switch (contentPosition)
case POSITION_BOTTOM_LEFT:
startX = 0;
startY = imgHeight - fontSize * lineCount - lineSpacing * (lineCount - 1) + fontSize - (fontSize / 6);
break;
case POSITION_BOTTOM_RIGHT:
startX = imgWidth - maxLength;
startY = imgHeight - fontSize * lineCount - lineSpacing * (lineCount - 1) + fontSize - (fontSize / 6);
break;
case POSITION_TOP_LEFT:
startX = 0;
startY = fontSize - (fontSize / 6);
break;
case POSITION_TOP_RIGHT:
startX = imgWidth - maxLength;
startY = fontSize - (fontSize / 6);
break;
default:
// 默认位于左下角
startX = 0;
startY = imgHeight - fontSize * lineCount - lineSpacing * (lineCount - 1) + fontSize - (fontSize / 6);
for (int i = 0; i < contentLines.size(); i++)
graphics.drawString(contentLines.get(i), startX, startY + i * (fontSize + lineSpacing));
graphics.dispose();
return bufferedImage;
/**
* 将文字转换为透明背景的图片
*
* @param contentLines
* 文本
* @param fontSize
* 字体大小(像素)
*
* @return 图片
* @see ImgUtil#strConvertToImg(List, Font, Color, int)
*/
public static BufferedImage strConvertToImg(List<String> contentLines, int fontSize)
return strConvertToImg(contentLines, new Font("微软雅黑", Font.PLAIN, fontSize),
new Color(255, 255, 255), DEFAULT_LINE_SPACING);
/**
* 将文字转换为透明背景的图片
*
* @return 图片
* @see ImgUtil#strConvertToImg(List, Font, Color, int)
*/
public static BufferedImage strConvertToImg(List<String> contentLines, Font font, Color fontColor)
return strConvertToImg(contentLines, font, fontColor, DEFAULT_LINE_SPACING);
/**
* 将文字转换为透明背景的图片
*
* @param contentLines
* 文本
* @param font
* 字
* @param fontColor
* 字体颜色
* @param lineSpacing
* 行间距(单位: 像素)
*
* @return 图片
*/
public static BufferedImage strConvertToImg(List<String> contentLines, Font font, Color fontColor,
int lineSpacing)
int fontSize = font.getSize();
if (fontSizeIsIllegal(fontSize))
throw new IllegalArgumentException("fontSize cannot less than 0 or equal 0.");
// step1. 计算文本的行数以及最大长度
Triple<Integer, Integer, Integer> triple = computeLineCountAndMaxLength(null, contentLines, font);
int lineCount = triple.getLeft();
Integer middle = triple.getMiddle();
Objects.requireNonNull(middle, "middle should not be null while fontSize > 0.");
int width = middle;
// step2. 根据字体大小,计算高度
int height = fontSize * lineCount + (lineCount - 1) * lineSpacing;
// step3. 创建 图形1(图层1) 作为 底色
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = bufferedImage.createGraphics();
graphics.clearRect(0, 0, width, height);
bufferedImage = graphics.getDeviceConfiguration().createCompatibleImage(width, height,
Transparency.TRANSLUCENT);
graphics.dispose();
// step4. 创建 图形2(图层2) 勾画文本
graphics = bufferedImage.createGraphics();
graphics.setColor(fontColor);
graphics.setFont(font);
// x向右为正, y向下为正
int startX = 0;
// 这里发现:还需要 调整(fontSize / 6)后,文字才能正好显示
int startY = height - fontSize * lineCount - lineSpacing * (lineCount - 1) + fontSize - (fontSize / 6);
for (int i = 0; i < contentLines.size(); i++)
graphics.drawString(contentLines.get(i), startX, startY + i * (fontSize + lineSpacing));
graphics.dispose();
return bufferedImage;
/**
* 给图片添加水印
* <br/>
* 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
*
* @return 图片(与入参bufferedImage是同一个对象)
* @see ImgUtil#addWatermark(BufferedImage, List, Font, Color, int, int)
*/
public static BufferedImage addWatermark(BufferedImage bufferedImage, List<String> contentLines)
return addWatermark(bufferedImage, contentLines, new Font("微软雅黑", Font.PLAIN, 0), new Color(255, 255, 255), DEFAULT_LINE_SPACING, POSITION_BOTTOM_LEFT);
/**
* 给图片添加水印
* <br/>
* 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
*
* @return 图片(与入参bufferedImage是同一个对象)
* @see ImgUtil#addWatermark(BufferedImage, List, Font, Color, int, int)
*/
public static BufferedImage addWatermark(BufferedImage bufferedImage, List<String> contentLines, Font font, Color fontColor)
return addWatermark(bufferedImage, contentLines, font, fontColor, DEFAULT_LINE_SPACING, POSITION_BOTTOM_LEFT);
/**
* 给图片添加水印
* <br/>
* 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
*
* @param bufferedImage
* 图片
* @param contentLines
* 文本
* @param font
* 字
* @param fontColor
* 字体颜色
* @param lineSpacing
* 行间距(单位: 像素)
* @param contentPosition
* 文字位置 <br />
* @link ImgUtil#POSITION_BOTTOM_LEFT
* @link ImgUtil#POSITION_BOTTOM_RIGHT
* @link ImgUtil#POSITION_TOP_LEFT
* @link ImgUtil#POSITION_TOP_RIGHT
*
* @return 图片(与入参bufferedImage是同一个对象)
*/
public static BufferedImage addWatermark(BufferedImage bufferedImage, List<String> contentLines,
Font font, Color fontColor, int lineSpacing, int contentPosition)
if (bufferedImage == null)
throw new IllegalArgumentException("bufferedImage cannot be null.");
// step1. 计算文本的行数以及最大长度
Triple<Integer, Integer, Integer> triple = computeLineCountAndMaxLength(bufferedImage, contentLines, font);
word文档的底色怎么消除?