You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java如何实现向图片添加文本并自适应适配指定矩形区域

Java 图片文本自动换行+字号自适应适配矩形区域实现

实现逻辑

  • 先从最大预设字号开始逐步缩小字号,逐一验证当前字号下,文本按矩形宽度自动换行后的总高度是否小于等于矩形高度,找到能完整放下所有文本的最大字号
  • 自动换行时按字符粒度拆分,保证每行宽度不超过矩形的最大宽度
  • 所有行整体在矩形区域内水平+垂直居中

完整实现代码

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;

public class ImageTextAdaptive {
    public static void main(String[] args) throws IOException {
        BufferedImage image = ImageIO.read(new File("img.png"));
        Graphics2D g2d = (Graphics2D) image.getGraphics();
        // 开启抗锯齿让文本更清晰
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        
        // 定义文本要适配的矩形区域,这里示例用整个图片,你可以改成自定义尺寸的矩形
        Rectangle targetRect = new Rectangle(0, 0, image.getWidth(), image.getHeight());
        String content = "TexvzgdsfadvcfkgsdASKJDFHJGgkdgfsakagjASGHDJStTexvzgdsfadvcfkgsdASKJDFHJGgkdgfsakagjASGHDJSt";
        
        // 绘制自适应文本
        drawAdaptiveCenteredText(g2d, content, targetRect);
        
        g2d.dispose();
        ImageIO.write(image, "png", new File("out.png"));
    }

    /**
     * 绘制自适应居中的文本,自动换行+自动调整字号适配矩形区域
     */
    public static void drawAdaptiveCenteredText(Graphics2D g2d, String text, Rectangle rect) {
        // 初始最大字号,可根据需求调整
        float maxFontSize = 72f;
        float minFontSize = 6f;
        Font currentFont = g2d.getFont().deriveFont(maxFontSize);
        List<String> wrappedLines = new ArrayList<>();
        float finalFontSize = maxFontSize;

        // 逐步缩小字号,直到找到能放下所有文本的最大字号
        while (finalFontSize >= minFontSize) {
            currentFont = g2d.getFont().deriveFont(finalFontSize);
            FontMetrics metrics = g2d.getFontMetrics(currentFont);
            wrappedLines = wrapText(text, metrics, rect.width);
            // 计算所有行的总高度
            int totalHeight = wrappedLines.size() * metrics.getHeight();
            if (totalHeight <= rect.height) {
                break;
            }
            finalFontSize--;
        }

        // 绘制所有行,整体居中
        FontMetrics finalMetrics = g2d.getFontMetrics(currentFont);
        g2d.setFont(currentFont);
        int lineHeight = finalMetrics.getHeight();
        int totalTextHeight = wrappedLines.size() * lineHeight;
        // 垂直居中的起始y坐标
        int currentY = rect.y + (rect.height - totalTextHeight) / 2 + finalMetrics.getAscent();

        for (String line : wrappedLines) {
            // 每行水平居中
            int x = rect.x + (rect.width - finalMetrics.stringWidth(line)) / 2;
            g2d.drawString(line, x, currentY);
            currentY += lineHeight;
        }
    }

    /**
     * 按指定宽度自动换行,返回拆分后的行列表
     */
    private static List<String> wrapText(String text, FontMetrics metrics, int maxWidth) {
        List<String> lines = new ArrayList<>();
        StringBuilder currentLine = new StringBuilder();
        for (char c : text.toCharArray()) {
            currentLine.append(c);
            if (metrics.stringWidth(currentLine.toString()) > maxWidth) {
                // 超过宽度就去掉最后一个字符,把当前行加入列表,然后用最后一个字符开启新行
                currentLine.deleteCharAt(currentLine.length() - 1);
                lines.add(currentLine.toString());
                currentLine = new StringBuilder(String.valueOf(c));
            }
        }
        // 加入最后一行
        if (currentLine.length() > 0) {
            lines.add(currentLine.toString());
        }
        return lines;
    }
}

关键参数调整说明

  • 可以修改maxFontSize和minFontSize的初始值,适配你的业务场景需要的字号范围
  • 如果需要按单词换行(仅针对英文场景),可以修改wrapText方法的拆分逻辑,按空格拆分后计算整词宽度,避免单词被截断
  • 如果要设置文本颜色,在调用drawString前调用g2d.setColor()方法设置即可

内容的提问来源于stack exchange,提问作者Fabio grossi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:39:01