Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Java - Overlay text onto image - Graphics.drawString..

Options
  • 02-03-2009 12:10pm
    #1
    Registered Users Posts: 841 ✭✭✭


    Hello,

    Looking for some help to do a fairly simple graphics-based operation. I have a picture. I want to overlay text onto the picture and save the result to a new file.

    Here is what I have so far (most of it solved!). I can add text to the image and save the result to a new file but for some reason my attempts to change the font have no effect. I have attached the image 03.png if anybody wants to give it a quick try (save it to C:\temp).
    import java.awt.Font;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import javax.imageio.ImageIO;
    
    public class ImageWithTextDemo 
    {
        public ImageWithTextDemo()
        {
    	try
    	{
    	    String tempfolder = "C:\\temp\\";
    	    
    	    File Ftempfolder = new File(tempfolder);
    	    BufferedImage background=ImageIO.read(new File(Ftempfolder,"03.png"));
    	    background.getGraphics().setFont(new Font("Times New Roman",Font.BOLD,32));
    	    background.getGraphics().drawString("Testing",20,160);
    	    ImageIO.write(background,"png",new File(Ftempfolder,"03-modified.png"));
    	}
    	catch(Exception e)
    	{
    	    e.printStackTrace();
    	}
        }
        public static void main(String args[])
        {
    	ImageWithTextDemo app = new ImageWithTextDemo();
        }
    }
    

    Here are some points to note:
    - I want the text to be centred on the image (not sure how to do this with Graphics.drawString or if it's possible). I am very familiar with such tricks using Swing (JLabel). Can a JLabel object be added here instead somehow?
    - I want to preserve the transparency of the input png image (the corners of 03.png are rounded with transparent background) - which I have managed to do in the above example.

    Thanks,
    Brian

    PS - This is not a school project! It is a small part of a much larger work-related project I have been working on for the past couple of years. I'm sure I could do it if I muddled around with it for half a day but I don't have a day to investigate the matter so I was hoping for a quick fix here :pac: I have been programming for 7-8 years but haven't really done much with graphics objects and applets since 1st year in college 9 years ago (mostly just Swing-based applications).


Comments

  • Registered Users Posts: 799 ✭✭✭eoinbn


    Here is your problem:
    background.getGraphics().setFont(new Font("Times New Roman",Font.BOLD,32));
    	    background.getGraphics().drawString("Testing",20,160);
    

    The first line draws the image and sets the font for that image.
    Your second line recreates the object, writes the string, but the font is back to the default as it's a new object.

    createGraphics() is just a newer version of getGraphics().

    File Ftempfolder = new File(tempfolder);
    	    System.out.print(tempfolder);
    	    BufferedImage background=ImageIO.read(new File(Ftempfolder,"03.png"));
    	    Graphics2D storeImg = background.createGraphics();
    	    storeImg.setFont(new Font("Times New Roman",Font.BOLD,32));
    	    storeImg.drawString("Testing",20,160);
    	    ImageIO.write(background,"png",new File(Ftempfolder,"03-modified.png"));
    


  • Registered Users Posts: 841 ✭✭✭Dr Pepper


    Excellent! Thanks Eoinbn

    I had a feeling there would be a fairly simple explanation alright - didn't realise that getGraphics() was creating a new object each time instead of just referring to the same object repeatedly.

    Anybody have an ideas for centring the text?


  • Registered Users Posts: 841 ✭✭✭Dr Pepper


    Got the centring thing sorted. I used the FontMetrics class to determine the width of the text to be drawn and then just used a simple formula to centre it on the picture [(picwidth/2)-(textwidth/2)]. Bit of a hack but it will do nicely for my requirements. (i.e. You could make a method/class to draw a string with a certain position and justification but I can't be bothered).
    Just in case anybody's looking at this future though, the class DrawString in this library does that, but I don't like to have to include whole libraries just to perform one simple operation.

    Thanks again,
    Brian
    String tempfolder = "C:\\temp\\";
    	    File Ftempfolder = new File(tempfolder);
    	    BufferedImage background=ImageIO.read(new File(Ftempfolder,"03.png"));
    	    Graphics2D storeImg = background.createGraphics();
    	    storeImg.setFont(new Font("Times New Roman",Font.BOLD,32));
    	    
    	    FontMetrics fm = storeImg.getFontMetrics();
    	    String message = "Testing";
    	    int textwidth = fm.stringWidth(message);
    	    int picwidth = background.getWidth();
    	    
    	    storeImg.drawString(message,(picwidth/2)-(textwidth/2),182);
    	    ImageIO.write(background,"png",new File(Ftempfolder,"03-modified.png"));
    


  • Registered Users Posts: 799 ✭✭✭eoinbn


    Get the centre of your pic. You might need to use java.awt.Image for that. I am too lazy so I am going to cheat and just look at the H*W of your picture which is 208*208 so I know the centre is 104*104.
    FontMetrics metrics = storeImg.getFontMetrics(new Font("Times New Roman",Font.BOLD,32));
    int height = metrics.getHeight(); //Average Height of a string
    int width = metrics.stringWidth("Testing");
    

    That returned 101, 38. Knowing these you can work out where you need to start your string of text. I came up with 54,123 which is little below centre, but not too bad.

    edit: I hit reply before your last post and didn't submit it for a while. It seems we are both fond of bad coding practices!


Advertisement