本文介绍如何使用 Java 程序在图片下方居中添加文字,以及中文字体的判断与加载。
准备
本例使用的图片如下,尺寸为1000 * 1000
:
代码逻辑
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
public class AddTextToImage {
public static void main(String[] args) throws Exception {
// 加载原图
BufferedImage originalImage = ImageIO.read(new File("/Users/lin/Desktop/demo.jpg"));
// 添加的文字
String text = "机器猫";
// 加载字体
Font font = loadFont("宋体", Font.BOLD, 16);
// 创建新的图片,新图片比旧图高100
BufferedImage newImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight() + 100, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = newImage.createGraphics();
// 计算文字的宽高
FontMetrics metrics = graphics.getFontMetrics();
int textWidth = metrics.stringWidth(text);
int textHeight = metrics.getHeight();
// 计算文字的居中位置
int x = (newImage.getWidth() - textWidth) / 2;
int y = originalImage.getHeight() + 50; // 50:文字在图片下方的距离
// 在新图上绘制文字
graphics.setFont(font);
graphics.drawString(text, x, y);
// 将原始图片的内容复制到新图片上
graphics.drawImage(originalImage, 0, 0, null);
// 保存新图片
ImageIO.write(newImage, "jpg", new File("/Users/lin/Desktop/demo_new.jpg"));
graphics.dispose();
}
/**
* 加载字体。
* 指定的字体不支持中文的话,则使用系统中支持中文的字体
*
* @param fontName 字体名称
* @param style 样式
* @param size 字体大小
* @return
*/
public static Font loadFont(String fontName, int style, int size) {
// “中”子的 unicode 编码
char verifyText = '\u4e2d';
Font font = new Font(fontName, Font.BOLD, 16);
if (font.canDisplay(verifyText)) {
return font;
}
Font[] systemFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
for (Font systemFont : systemFonts) {
if (systemFont.canDisplay(verifyText)) {
return systemFont;
}
}
return font;
}
}
生成效果:
优化
生成的图片有 2 个问题:
- 尺寸由原来的
1000 * 1000
变成1000 * 1100
- 增加的高度为黑色的背景
优化结果:
- 维持新图尺寸的对称,变为
1100 * 1100
- 使用原背景色填充新增加的背景
代码实现:
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
public class AddTextToImage {
public static void main(String[] args) throws Exception {
// 加载原图
BufferedImage originalImage = ImageIO.read(new File("/Users/lin/Desktop/demo.jpg"));
// 添加的文字
String text = "机器猫";
// 加载字体
Font font = loadFont("宋体", Font.BOLD, 16);
// 创建新的图片,新图片比旧图宽100,高100
BufferedImage newImage = new BufferedImage(originalImage.getWidth() + 100, originalImage.getHeight() + 100, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = newImage.createGraphics();
// 设置抗锯齿
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//设置新图背景色
graphics.setColor(new Color(222,235,252));
graphics.fillRect(0, 0, newImage.getWidth(), newImage.getHeight());
// 将原始图片的内容复制到新图片上,原图在新图上左右居中
graphics.drawImage(originalImage, 50, 0, null);
// 计算文字的宽高
FontMetrics metrics = graphics.getFontMetrics();
int textWidth = metrics.stringWidth(text);
int textHeight = metrics.getHeight();
int ascent = metrics.getAscent();//字符最高点距离基线上方的距离
// 计算文字的居中位置
int x = (newImage.getWidth() - textWidth) / 2;
int y = originalImage.getHeight() + (100 - textHeight) / 2 + ascent; // 文字在图片下方 100 区域内的上下居中距离
// 在新图上绘制文字
graphics.setFont(font);
graphics.setColor(Color.BLACK);
graphics.drawString(text, x, y);
// 保存新图片
ImageIO.write(newImage, "jpg", new File("/Users/lin/Desktop/demo_new.jpg"));
graphics.dispose();
}
/**
* 加载字体。
* 指定的字体不支持中文的话,则使用系统中支持中文的字体
*
* @param fontName 字体名称
* @param style 样式
* @param size 字体大小
* @return
*/
public static Font loadFont(String fontName, int style, int size) {
// “中”子的 unicode 编码
char verifyText = '\u4e2d';
Font font = new Font(fontName, Font.BOLD, 16);
if (font.canDisplay(verifyText)) {
return font;
}
Font[] systemFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
for (Font systemFont : systemFonts) {
if (systemFont.canDisplay(verifyText)) {
return systemFont;
}
}
return font;
}
}
生成效果: