(Edit: Answer was rewritten - see history for details)
The task that is indicated in the example image may in fact be a bit tricky: Namely, having multi-line text. But one simple solution here is to use a JLabel
and a CellRendererPane
for rendering the text, because it also supports HTML. So for a title like
String title =
"<html><font size=4>This <font color=#FF0000><b>Text</b></font><br>" +
"with line breaks<br>" +
"will be the title</font></html>");
with line breaks and colors and a dedicated font size, one can obtain the appropriate image:

Here is an example showing how this may be achieved:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.swing.CellRendererPane;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class TitleAdder
{
public static void main(String[] args)
{
addTitle("yS2aQ.png", "output.png",
"<html><font size=4>This <font color=#FF0000><b>Text</b></font><br>" +
"with line breaks<br>" +
"will be the title</font></html>");
}
private static void addTitle(
String inputFileName, String outputFileName, String title)
{
try (InputStream in = new FileInputStream(inputFileName);
OutputStream out = new FileOutputStream(outputFileName))
{
BufferedImage sourceImage = ImageIO.read(in);
BufferedImage targetImage =
addTitle(sourceImage, title);
ImageIO.write(targetImage, "png", out);
// Show the image, for testing
show(targetImage);
}
catch (IOException e)
{
e.printStackTrace();
}
}
private static BufferedImage addTitle(
BufferedImage sourceImage, String title)
{
JLabel label = new JLabel(title);
label.setBackground(Color.WHITE);
label.setForeground(Color.BLACK);
label.setOpaque(true);
int titleHeight = label.getPreferredSize().height;
int height = sourceImage.getHeight() + titleHeight;
BufferedImage targetImage = new BufferedImage(
sourceImage.getWidth(), height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = targetImage.createGraphics();
SwingUtilities.paintComponent(g, label, new CellRendererPane(),
0, 0, sourceImage.getWidth(), titleHeight);
g.drawImage(sourceImage, 0, titleHeight, null);
g.dispose();
return targetImage;
}
private static void show(final BufferedImage image)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
JFrame f = new JFrame();
f.getContentPane().add(new JLabel(new ImageIcon(image)));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}