字符串到 BufferedImage,设置边框和新行
String to BufferedImage with set borders and new line
我是 Whosebug 的新手,需要帮助解决以下问题。
背景:
我必须为学校做一个项目,在那里我们得到一个打印东西的乐高头脑风暴机器人(基于坐标)。
我的想法是在 Java 中实现程序,该程序翻译(Google 翻译 API)给定的输入,使用该字符串创建 BufferedImage,然后读出该图像的坐标,因此机器人可以 draw/print 翻译输入。
除了将文本写入 BufferedImage 之外,我的一切都正常工作了。
问题:
我正在寻找一种使用输入字符串创建 BufferedImage 的方法。图像应该有固定的边界(160x200 像素,因为这是机器人坐标系的大小)。我设法创建了一个带有所述边框的 BufferedImage,但是当我在图像上插入字符串时,它只留下图像,因此字符串的后部丢失了。
是否可以在 BufferedImage 到达边界时自动在 BufferedImage 中创建一个新行?
我现在只担心宽度,所以这不是问题,如果它在底部被切断(尽管如果您知道如何更改也可以告诉我)。
字体应为:
Font font = new Font("Arial", Font.PLAIN, 25);
因为它支持我使用的语言。
感谢您的帮助!
TL;DR: 具有固定大小和字符串作为内容的 BufferedImage。字符串不应该被截断:换行,如果字符串到达边界,没有单词被截断。
好吧,既然有人告诉我 post 我的答案(尽管这会阻止未来的人自己完成作业),就在这里。
class 从给定的输入字符串创建一个 BufferedImage (160x200 px)(还将图像保存为源文件夹中的文件)。
我确信它仍然可以改进,但我不知道如何改进,因为这就是我从这里得到的帮助中设法做到的。
example output of an image
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
public class TextToImage {
public static BufferedImage createImage(String inputString) throws IOException{
BufferedImage image = createGraphics(inputString);
saveImage(image);
return image;
}
public static BufferedImage createGraphics(String inputString) {
BufferedImage bufferedImage = new BufferedImage(160, 195, BufferedImage.TYPE_INT_RGB);
Font font = new Font("Arial", Font.PLAIN, 25);
Graphics2D graphics2D = prepareGraphics(bufferedImage);
double baseY = getY(getBounds(font, inputString, graphics2D));
if(isLatin(inputString)) {
drawLinesAsWords(graphics2D, inputString, font, baseY);
} else {
drawLinesAsCharacters(graphics2D, inputString, font, baseY);
}
graphics2D.dispose();
return bufferedImage;
}
public static double getY(Rectangle2D bounds) {
double ascent = - bounds.getY();
double baseY = 0 + ascent;
return baseY;
}
public static Rectangle2D getBounds(Font font, String content, Graphics2D graphics2D) {
FontRenderContext context = graphics2D.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(content, context);
return bounds;
}
public static Graphics2D prepareGraphics(BufferedImage bufferedImage) {
Graphics2D graphics2D = (Graphics2D)bufferedImage.getGraphics();
graphics2D.setBackground(Color.GRAY);
graphics2D.clearRect(0, 0, 160, 195);
graphics2D.setPaint(Color.BLACK);
return graphics2D;
}
public static boolean isLatin(String inputString) {
String regex = "^.*\p{IsLatin}.*";
boolean result = inputString.matches(regex);
if(result) {
return true;
} else {
return false;
}
}
public static void saveImage(BufferedImage bufferedImage) throws IOException {
ImageIO.write(bufferedImage, "png", new File("./Image.jpeg"));
}
public static int getHeight(Font font, Graphics2D g) {
int lineHeight = g.getFontMetrics(font).getHeight();
return lineHeight;
}
public static void drawLinesAsWords(Graphics2D graphics2D, String content, Font font, double baseY) {
int lineHeight = getHeight(font, graphics2D);
int leftBorder = 5;
String[] wordArray = content.split(" ");
FontMetrics fontMetrics = graphics2D.getFontMetrics(font);
String currentContent = "";
double leftTopCornerLine = baseY;
for(int i = 0; i < wordArray.length; i++) {
if(leftTopCornerLine < 195) {
if(fontMetrics.stringWidth(currentContent)>=240) {
if(fontMetrics.stringWidth(wordArray[i])<=240-fontMetrics.stringWidth(currentContent)) {
currentContent += " " + wordArray[i];
graphics2D.drawString(currentContent, leftBorder, (int)leftTopCornerLine);
currentContent ="";
leftTopCornerLine += lineHeight;
} else {
graphics2D.drawString(currentContent, leftBorder, (int)leftTopCornerLine);
currentContent ="";
leftTopCornerLine += lineHeight;
}
} else {
int contentWidth = fontMetrics.stringWidth(currentContent);
if(contentWidth<=260) {
currentContent += " " + wordArray[i];
}
}
} else {
System.out.println("Input was cut, because it was too long.");
break;
}
}
}
public static void drawLinesAsCharacters(Graphics2D graphics2D, String content, Font font, double baseY) {
int lineHeight = getHeight(font, graphics2D);
int leftBorder = 5;
String[] characterArray = content.split("");
FontMetrics fontMetrics = graphics2D.getFontMetrics(font);
String currentContent = "";
double leftTopCornerLine = baseY;
for(int i = 0; i < characterArray.length; i++) {
if(leftTopCornerLine < 195) {
if(fontMetrics.stringWidth(currentContent)>=210) {
if(fontMetrics.stringWidth(characterArray[i])<=210-fontMetrics.stringWidth(currentContent)) {
currentContent += characterArray[i];
graphics2D.drawString(currentContent, leftBorder, (int)leftTopCornerLine);
currentContent ="";
leftTopCornerLine += lineHeight;
} else {
graphics2D.drawString(currentContent, leftBorder, (int)leftTopCornerLine);
currentContent ="";
leftTopCornerLine += lineHeight;
}
} else {
int contentWidth = fontMetrics.stringWidth(currentContent);
if(contentWidth<=230) {
currentContent += characterArray[i];
}
}
} else {
System.out.println("Input was cut, because it was too long.");
break;
}
}
}
}
我是 Whosebug 的新手,需要帮助解决以下问题。
背景:
我必须为学校做一个项目,在那里我们得到一个打印东西的乐高头脑风暴机器人(基于坐标)。 我的想法是在 Java 中实现程序,该程序翻译(Google 翻译 API)给定的输入,使用该字符串创建 BufferedImage,然后读出该图像的坐标,因此机器人可以 draw/print 翻译输入。 除了将文本写入 BufferedImage 之外,我的一切都正常工作了。
问题:
我正在寻找一种使用输入字符串创建 BufferedImage 的方法。图像应该有固定的边界(160x200 像素,因为这是机器人坐标系的大小)。我设法创建了一个带有所述边框的 BufferedImage,但是当我在图像上插入字符串时,它只留下图像,因此字符串的后部丢失了。 是否可以在 BufferedImage 到达边界时自动在 BufferedImage 中创建一个新行?
我现在只担心宽度,所以这不是问题,如果它在底部被切断(尽管如果您知道如何更改也可以告诉我)。 字体应为:
Font font = new Font("Arial", Font.PLAIN, 25);
因为它支持我使用的语言。
感谢您的帮助!
TL;DR: 具有固定大小和字符串作为内容的 BufferedImage。字符串不应该被截断:换行,如果字符串到达边界,没有单词被截断。
好吧,既然有人告诉我 post 我的答案(尽管这会阻止未来的人自己完成作业),就在这里。 class 从给定的输入字符串创建一个 BufferedImage (160x200 px)(还将图像保存为源文件夹中的文件)。 我确信它仍然可以改进,但我不知道如何改进,因为这就是我从这里得到的帮助中设法做到的。
example output of an image
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
public class TextToImage {
public static BufferedImage createImage(String inputString) throws IOException{
BufferedImage image = createGraphics(inputString);
saveImage(image);
return image;
}
public static BufferedImage createGraphics(String inputString) {
BufferedImage bufferedImage = new BufferedImage(160, 195, BufferedImage.TYPE_INT_RGB);
Font font = new Font("Arial", Font.PLAIN, 25);
Graphics2D graphics2D = prepareGraphics(bufferedImage);
double baseY = getY(getBounds(font, inputString, graphics2D));
if(isLatin(inputString)) {
drawLinesAsWords(graphics2D, inputString, font, baseY);
} else {
drawLinesAsCharacters(graphics2D, inputString, font, baseY);
}
graphics2D.dispose();
return bufferedImage;
}
public static double getY(Rectangle2D bounds) {
double ascent = - bounds.getY();
double baseY = 0 + ascent;
return baseY;
}
public static Rectangle2D getBounds(Font font, String content, Graphics2D graphics2D) {
FontRenderContext context = graphics2D.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(content, context);
return bounds;
}
public static Graphics2D prepareGraphics(BufferedImage bufferedImage) {
Graphics2D graphics2D = (Graphics2D)bufferedImage.getGraphics();
graphics2D.setBackground(Color.GRAY);
graphics2D.clearRect(0, 0, 160, 195);
graphics2D.setPaint(Color.BLACK);
return graphics2D;
}
public static boolean isLatin(String inputString) {
String regex = "^.*\p{IsLatin}.*";
boolean result = inputString.matches(regex);
if(result) {
return true;
} else {
return false;
}
}
public static void saveImage(BufferedImage bufferedImage) throws IOException {
ImageIO.write(bufferedImage, "png", new File("./Image.jpeg"));
}
public static int getHeight(Font font, Graphics2D g) {
int lineHeight = g.getFontMetrics(font).getHeight();
return lineHeight;
}
public static void drawLinesAsWords(Graphics2D graphics2D, String content, Font font, double baseY) {
int lineHeight = getHeight(font, graphics2D);
int leftBorder = 5;
String[] wordArray = content.split(" ");
FontMetrics fontMetrics = graphics2D.getFontMetrics(font);
String currentContent = "";
double leftTopCornerLine = baseY;
for(int i = 0; i < wordArray.length; i++) {
if(leftTopCornerLine < 195) {
if(fontMetrics.stringWidth(currentContent)>=240) {
if(fontMetrics.stringWidth(wordArray[i])<=240-fontMetrics.stringWidth(currentContent)) {
currentContent += " " + wordArray[i];
graphics2D.drawString(currentContent, leftBorder, (int)leftTopCornerLine);
currentContent ="";
leftTopCornerLine += lineHeight;
} else {
graphics2D.drawString(currentContent, leftBorder, (int)leftTopCornerLine);
currentContent ="";
leftTopCornerLine += lineHeight;
}
} else {
int contentWidth = fontMetrics.stringWidth(currentContent);
if(contentWidth<=260) {
currentContent += " " + wordArray[i];
}
}
} else {
System.out.println("Input was cut, because it was too long.");
break;
}
}
}
public static void drawLinesAsCharacters(Graphics2D graphics2D, String content, Font font, double baseY) {
int lineHeight = getHeight(font, graphics2D);
int leftBorder = 5;
String[] characterArray = content.split("");
FontMetrics fontMetrics = graphics2D.getFontMetrics(font);
String currentContent = "";
double leftTopCornerLine = baseY;
for(int i = 0; i < characterArray.length; i++) {
if(leftTopCornerLine < 195) {
if(fontMetrics.stringWidth(currentContent)>=210) {
if(fontMetrics.stringWidth(characterArray[i])<=210-fontMetrics.stringWidth(currentContent)) {
currentContent += characterArray[i];
graphics2D.drawString(currentContent, leftBorder, (int)leftTopCornerLine);
currentContent ="";
leftTopCornerLine += lineHeight;
} else {
graphics2D.drawString(currentContent, leftBorder, (int)leftTopCornerLine);
currentContent ="";
leftTopCornerLine += lineHeight;
}
} else {
int contentWidth = fontMetrics.stringWidth(currentContent);
if(contentWidth<=230) {
currentContent += characterArray[i];
}
}
} else {
System.out.println("Input was cut, because it was too long.");
break;
}
}
}
}