向图像添加文本并使其适合 Java 中的矩形区域
Adding text to an image and make it fit into a rectangular region in Java
我正在尝试使用以下代码向 Java 中的图像添加一些文本:
public static void main(String[] args) throws IOException {
BufferedImage image = ImageIO.read(new File("img.png"));
Graphics g = image.getGraphics();
Rectangle rectangle = new Rectangle(image.getWidth(), image.getHeight());
g.setFont(g.getFont().deriveFont(30f));
drawCenteredString(g, "TexvzgdsfadvcfkgsdASKJDFHJGgkdgfsakagjASGHDJStTexvzgdsfadvcfkgsdASKJDFHJGgkdgfsakagjASGHDJSt", rectangle, g.getFont());
g.dispose();
ImageIO.write(image, "png", new File("out.png"));
}
public static void drawCenteredString(Graphics g, String text, Rectangle rect, Font font) {
FontMetrics metrics = g.getFontMetrics(font);
int x = rect.x + (rect.width - metrics.stringWidth(text)) / 2;
int y = rect.y + ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent();
g.setFont(font);
g.drawString(text, x, y);
}
但我有一个问题:我需要能够缩放字体大小或将文字发送到新行,以便整个字符串适合图像中心的最大尺寸为x,y。
我该怎么做?
我使用了在网上找到的图片。基本上,您尝试使用较大的字体大小并减小字体大小,直到您的文本适合图像。
这是我添加文字后的图片。
我从 96 的字体大小开始,然后逐渐减小到 46,适合图像。
这是完整的可运行代码。
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
public class AddTextToImage {
public static void main(String[] args) throws IOException {
URL url = new URL("https://clipartmag.com/images/car-cartoon-png-18.png");
BufferedImage image = ImageIO.read(url);
Graphics g = image.getGraphics();
Rectangle rectangle = new Rectangle(image.getWidth(), image.getHeight());
String text = "TexvzgdsfadvcfkgsdASKJDFHJGgkdgfsakagjASGHDJSt"
+ "TexvzgdsfadvcfkgsdASKJDFHJGgkdgfsakagjASGHDJSt";
int fontSize = 98;
FontMetrics metrics;
do {
fontSize -= 2;
g.setFont(g.getFont().deriveFont((float) fontSize));
metrics = g.getFontMetrics(g.getFont());
} while (metrics.stringWidth(text) > rectangle.width);
System.out.println("Font Size: " + fontSize);
drawCenteredString(g, text, rectangle, g.getFont());
g.dispose();
ImageIO.write(image, "png", new File("output.png"));
}
public static void drawCenteredString(Graphics g, String text, Rectangle rect, Font font) {
FontMetrics metrics = g.getFontMetrics(font);
int x = rect.x + (rect.width - metrics.stringWidth(text)) / 2;
int y = rect.y + ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent();
g.setFont(font);
g.drawString(text, x, y);
}
}
要换行文字,create TextLayout objects from a LineBreakMeasurer, and use TextLayout.draw 而不是用 Graphics.drawString 绘图。
首先,您需要创建一个 AttributedCharacterIterator。您可以通过从您的文本中创建一个 AttributedString 来做到这一点:
AttributedString attrStr = new AttributedString(text);
AttributedCharacterIterator iter = attrStr.getIterator();
现在您可以创建一个 LineBreakMeasurer:
Graphics2D g2 = (Graphics2D) g;
LineBreakMeasurer measurer = new LineBreakMeasurer(iter,
g2.getFontRenderContext());
然后您从 LineBreakMeasurer 中获取作为 TextLayouts 的行,一次一条:
List<TextLayout> lines = new ArrayList<>();
while (measurer.getPosition() < text.length()) {
lines.add(measurer.nextLayout(rect.width));
}
一旦你有了它们,你就可以计算出总高度:
float textHeight = 0;
for (TextLayout line : lines) {
textHeight += line.getAscent() + line.getDescent() + line.getLeading();
}
终于可以画线了:
float y = (rect.height - textHeight) / 2;
for (TextLayout line : lines) {
Rectangle2D bounds = line.getBounds();
float x = (rect.width - (float) bounds.getWidth()) / 2;
line.draw(g2, x, y + line.getAscent());
y += line.getAscent() + line.getDescent() + line.getLeading();
}
我正在尝试使用以下代码向 Java 中的图像添加一些文本:
public static void main(String[] args) throws IOException {
BufferedImage image = ImageIO.read(new File("img.png"));
Graphics g = image.getGraphics();
Rectangle rectangle = new Rectangle(image.getWidth(), image.getHeight());
g.setFont(g.getFont().deriveFont(30f));
drawCenteredString(g, "TexvzgdsfadvcfkgsdASKJDFHJGgkdgfsakagjASGHDJStTexvzgdsfadvcfkgsdASKJDFHJGgkdgfsakagjASGHDJSt", rectangle, g.getFont());
g.dispose();
ImageIO.write(image, "png", new File("out.png"));
}
public static void drawCenteredString(Graphics g, String text, Rectangle rect, Font font) {
FontMetrics metrics = g.getFontMetrics(font);
int x = rect.x + (rect.width - metrics.stringWidth(text)) / 2;
int y = rect.y + ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent();
g.setFont(font);
g.drawString(text, x, y);
}
但我有一个问题:我需要能够缩放字体大小或将文字发送到新行,以便整个字符串适合图像中心的最大尺寸为x,y。 我该怎么做?
我使用了在网上找到的图片。基本上,您尝试使用较大的字体大小并减小字体大小,直到您的文本适合图像。
这是我添加文字后的图片。
我从 96 的字体大小开始,然后逐渐减小到 46,适合图像。
这是完整的可运行代码。
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
public class AddTextToImage {
public static void main(String[] args) throws IOException {
URL url = new URL("https://clipartmag.com/images/car-cartoon-png-18.png");
BufferedImage image = ImageIO.read(url);
Graphics g = image.getGraphics();
Rectangle rectangle = new Rectangle(image.getWidth(), image.getHeight());
String text = "TexvzgdsfadvcfkgsdASKJDFHJGgkdgfsakagjASGHDJSt"
+ "TexvzgdsfadvcfkgsdASKJDFHJGgkdgfsakagjASGHDJSt";
int fontSize = 98;
FontMetrics metrics;
do {
fontSize -= 2;
g.setFont(g.getFont().deriveFont((float) fontSize));
metrics = g.getFontMetrics(g.getFont());
} while (metrics.stringWidth(text) > rectangle.width);
System.out.println("Font Size: " + fontSize);
drawCenteredString(g, text, rectangle, g.getFont());
g.dispose();
ImageIO.write(image, "png", new File("output.png"));
}
public static void drawCenteredString(Graphics g, String text, Rectangle rect, Font font) {
FontMetrics metrics = g.getFontMetrics(font);
int x = rect.x + (rect.width - metrics.stringWidth(text)) / 2;
int y = rect.y + ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent();
g.setFont(font);
g.drawString(text, x, y);
}
}
要换行文字,create TextLayout objects from a LineBreakMeasurer, and use TextLayout.draw 而不是用 Graphics.drawString 绘图。
首先,您需要创建一个 AttributedCharacterIterator。您可以通过从您的文本中创建一个 AttributedString 来做到这一点:
AttributedString attrStr = new AttributedString(text);
AttributedCharacterIterator iter = attrStr.getIterator();
现在您可以创建一个 LineBreakMeasurer:
Graphics2D g2 = (Graphics2D) g;
LineBreakMeasurer measurer = new LineBreakMeasurer(iter,
g2.getFontRenderContext());
然后您从 LineBreakMeasurer 中获取作为 TextLayouts 的行,一次一条:
List<TextLayout> lines = new ArrayList<>();
while (measurer.getPosition() < text.length()) {
lines.add(measurer.nextLayout(rect.width));
}
一旦你有了它们,你就可以计算出总高度:
float textHeight = 0;
for (TextLayout line : lines) {
textHeight += line.getAscent() + line.getDescent() + line.getLeading();
}
终于可以画线了:
float y = (rect.height - textHeight) / 2;
for (TextLayout line : lines) {
Rectangle2D bounds = line.getBounds();
float x = (rect.width - (float) bounds.getWidth()) / 2;
line.draw(g2, x, y + line.getAscent());
y += line.getAscent() + line.getDescent() + line.getLeading();
}