Search code examples
javaimagegraphicsgraphics2djava-2d

Java How to add String below an image and resizing it?


I am trying to add a title string below a png image. The problem is that there is no space for the text and I have to add some white space. Im not sure how to do this. This is what I have done so far:

        BufferedImage image = ImageIO.read(new File("output.png"));
        Graphics g = image.getGraphics();
        g.setFont(g.getFont().deriveFont(30f));
        g.setColor(Color.BLACK);
        g.drawString("Hello World!", 100, 350);
        g.dispose();
        ImageIO.write(image, "png", new File("test.png"));

Solution

  • Why not simply add the spacing you need to the new BufferedImages height?

    Here is an example I made:

    enter image description here

    The real magic happens here:

    private BufferedImage drawTextOnImage(String text, BufferedImage image, int space) {
        BufferedImage bi = new BufferedImage(image.getWidth(), image.getHeight() + space, BufferedImage.TRANSLUCENT);
        Graphics2D g2d = (Graphics2D) bi.createGraphics();
        g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
        g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
        g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON));
    
        g2d.drawImage(image, 0, 0, null);
    
        g2d.setColor(Color.BLACK);
        g2d.setFont(new Font("Calibri", Font.BOLD, 20));
        FontMetrics fm = g2d.getFontMetrics();
        int textWidth = fm.stringWidth(text);
    
        //center text at bottom of image in the new space
        g2d.drawString(text, (bi.getWidth() / 2) - textWidth / 2, bi.getHeight());
    
        g2d.dispose();
        return bi;
    }
    

    The above method will allow you to pass in text, a reference to the image and the amount of spacing you want to add. It will than draw the string to the image within the specified space. The image is resized before passing it to the above method (drawTextOnImage(..)) via:

    public static BufferedImage resize(BufferedImage image, int width, int height) {
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
        Graphics2D g2d = (Graphics2D) bi.createGraphics();
        g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
        g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
        g2d.drawImage(image, 0, 0, width, height, null);
        g2d.dispose();
        return bi;
    }
    

    Test.java:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.net.URL;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class Test {
    
        public Test() {
            createAndShowGui();
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Test();
                }
            });
        }
    
        private void createAndShowGui() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            BufferedImage bi = null;
            try {
                bi = ImageIO.read(new URL("http://cs.anu.edu.au/student/comp6700/icons/DukeWithHelmet.png"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
    
            BufferedImage resizedImage = resize(bi, 200, 200);
    
            final BufferedImage textRenderedImage = drawTextOnImage("Hello", resizedImage, 15);
    
            JPanel p = new JPanel() {
                @Override
                protected void paintComponent(Graphics grphcs) {
                    super.paintComponent(grphcs);
                    Graphics2D g2d = (Graphics2D) grphcs;
                    g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
                    g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
                    g2d.drawImage(textRenderedImage, 0, 0, null);
                }
    
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(textRenderedImage.getWidth(), textRenderedImage.getHeight());
                }
            };
    
            frame.add(p);
            frame.pack();
            frame.setVisible(true);
        }
    
        private BufferedImage drawTextOnImage(String text, BufferedImage image, int space) {
            BufferedImage bi = new BufferedImage(image.getWidth(), image.getHeight() + space, BufferedImage.TRANSLUCENT);
            Graphics2D g2d = (Graphics2D) bi.createGraphics();
            g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
            g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
            g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON));
    
            g2d.drawImage(image, 0, 0, null);
    
            g2d.setColor(Color.BLACK);
            g2d.setFont(new Font("Calibri", Font.BOLD, 20));
            FontMetrics fm = g2d.getFontMetrics();
            int textWidth = fm.stringWidth(text);
    
            //center text at bottom of image in the new space
            g2d.drawString(text, (bi.getWidth() / 2) - textWidth / 2, bi.getHeight());
    
            g2d.dispose();
            return bi;
        }
    
        public static BufferedImage resize(BufferedImage image, int width, int height) {
            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
            Graphics2D g2d = (Graphics2D) bi.createGraphics();
            g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
            g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
            g2d.drawImage(image, 0, 0, width, height, null);
            g2d.dispose();
            return bi;
        }
    }