我查看了java.awt.Graphics文档,stackoverflow,找不到解决方案。我输入了两个东西,一个图像文件和多行文本(段落)。我需要在图像文件上写入多行文本,然后将其另存为新图像。想知道我是否遗漏了一些非常简单的东西。 我也愿意使用任何好的第三方库。
final BufferedImage image = ImageIO.read(new File("c:/anil/Lenna.png"));
Graphics g = image.getGraphics();
g.setFont(g.getFont().deriveFont(30f));
g.drawString("Hello world", 100, 100);
g.dispose();
上面的代码只在图像上写了一行。
答案 0 :(得分:1)
如果你想绘制几行,你必须明确地做...
所以第一步是检测'线
String str = ... //some text with line breaks;
String [] lines = str.spilt("\n"); //breaking the lines into an array
第二步是绘制所有行
Graphics g = image.getGraphics();
g.setFont(g.getFont().deriveFont(30f));
int lineHeight = g.getFontMetrics().getHeight();
//here comes the iteration over all lines
for(int lineCount = 0; lineCount < lines.length; lineCount ++){ //lines from above
int xPos = 100;
int yPos = 100 + lineCount * lineHeight;
String line = lines[lineCount];
g.drawString(line, xpos, yPos);
}
g.dispose();
答案 1 :(得分:1)
JLabel接受简单的html来格式化文本。然后你可以在你的图像上画它:
JLabel l=new JLabel("<html>line1<br>line2");
l.setSize(l.getPrefferedSize());
g.translate(10,10); // fixed location
l.paint(g);
编辑:完整示例
public class OP_32110247 extends JPanel {
private final JLabel l = new JLabel();
private final BufferedImage image;
public OP_32110247(String imgfile, String txt) throws IOException {
image = ImageIO.read(new URL(imgfile));
l.setText(txt);
l.setFont(getFont().deriveFont(Font.BOLD,30f));
l.setSize(l.getPreferredSize());
l.setForeground(Color.GREEN);
Dimension d = new Dimension(image.getWidth(), image.getHeight());
setPreferredSize(d);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension d = getSize();
g.drawImage(image, 0, 0, null);
//place text in center of image
g.translate((d.width-l.getWidth())/2, (d.height-l.getHeight())/2);
l.paint(g);
}
public static void main(String[] args) throws IOException {
String txt = "<html>line1<br>line2";
String image = "http://kysoft.pl/proj/java/j+c.png";
JFrame f = new JFrame();
f.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
f.setContentPane(new OP_32110247(image,txt));
f.pack();
f.setVisible(true);
}
}
答案 2 :(得分:0)
最佳解决方案是扩展JLabel
并覆盖paintComponent
。使用所需图像创建Label
。在调用super.paintComponent
之后绘制文本,每行使用字体指标定位在另一行之下。如下所示:
class ImageWithTextLabel extends JLabel {
List<String> lines = new ArrayList<>();
Point textPosition = new Point(0,0);
private Font textFont;
private ImageWithTextLabel(Icon image) {
super(image);
}
public void addText(String text) {
lines.add(text);
}
public void setTextPosition(Point textPosition) {
this.textPosition = textPosition;
}
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
int from = textPosition.y ;
g.setFont(textFont);
for (String line : lines) {
g.drawString(line, textPosition.x, from);
from += g.getFontMetrics().getHeight();
}
}
public void setTextFont(Font font) {
textFont = font;
}
}
答案 3 :(得分:0)
请参见Drawing Multiple Lines of Text(Oracle Java Tutorials)和complete code 使用LineBreakMeasurer:
int width = 400;
int height = 500;
BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setColor(Color.MAGENTA);
Hashtable<TextAttribute,Object> map = new Hashtable<TextAttribute,Object>();
map.put(TextAttribute.FAMILY, "微软雅黑");
map.put(TextAttribute.SIZE,new Float(18.0));
AttributedString vanGogh = new AttributedString(
"Many people 中国 believe that Vincent van Gogh painted his best works " +
"during the two-year period he spent in Provence. Here is where he " +
"painted The Starry Night--which some consider to be his greatest " +
"work of all. However, as his artistic brilliance reached new " +
"heights in Provence, his physical and mental health plummeted. ",
map);
AttributedCharacterIterator paragraph = vanGogh.getIterator();
int paragraphStart = paragraph.getBeginIndex();
int paragraphEnd = paragraph.getEndIndex();
FontRenderContext frc = g2d.getFontRenderContext();
LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(paragraph, frc);
float breakWidth = 250f;
float drawPosY = 20;
float drawPosx = 0f;
lineMeasurer.setPosition(paragraphStart);
while(lineMeasurer.getPosition()< paragraphEnd ){
TextLayout layout = lineMeasurer.nextLayout(breakWidth);
drawPosx = layout.isLeftToRight()?0:breakWidth-layout.getAdvance();
drawPosY += layout.getAscent();
layout.draw(g2d,drawPosx,drawPosY);
drawPosY += layout.getDescent() + layout.getLeading();
}
g2d.dispose();
File file = new File("myimage.png");
ImageIO.write(bufferedImage,"png",file);
file = new File("myimage.jpg");
ImageIO.write(bufferedImage,"jpg",file);