Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java awt font spacing options

Since the Brazilian government does not have a public API for postal codes, I am trying to reverse engineer the code that correios.com.br uses to generate the image below so I can generate my own images to train the OCR program.

alt text

I believe that I have already got almost everything right besides the text spacing and the colors:

alt text

I am not interested on the colors now, but the text spacing is really bothering me. For instance, have a look on the 'Ti' in 'Tijuca'. The two letters are really close together in the original image and I can't reproduce this feature. I have already tried to derive the font, setting values to TextAttribute.TRACKING and TextAttribute.KERNING, but it did not work.

Here follows my code:

import java.awt.Color;
import java.awt.font.TextAttribute;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import javax.imageio.ImageIO;

public class CreateImage {

    /**
     * @param args
     */
    public static void main(String[] args) {
        int width = 570;
        int height = 120;
        boolean new_image = true;

        BufferedImage img;       

        if (!new_image) {
            try {
                img = ImageIO.read(new File("original.jpg"));                           
            } catch (IOException e) {
                e.printStackTrace();            
                new_image = true;
                img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            }
        } else {
            img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);         
        }

        Graphics2D g2d = img.createGraphics();
        if (new_image) {
            // white background
            g2d.setPaint(Color.WHITE);
            g2d.fillRect(0, 0, width, height);

            g2d.setPaint(Color.BLACK);
        } else {
            g2d.setPaint(Color.RED);
        }


        Font myfont = new Font("SansSerif", Font.BOLD, 11);      

        /*
        Hashtable<TextAttribute, Float> attributes = new Hashtable<TextAttribute, Float>();
        attributes.put(TextAttribute.TRACKING, new Float(-0.01));
        myfont = myfont.deriveFont(attributes);
        */

        g2d.setFont(myfont);

        g2d.drawString("Logradouro:", 5, 13);
        g2d.drawString("Bairro:", 5, 33);
        g2d.drawString("Localidade / UF:", 5, 53);
        g2d.drawString("CEP:", 5, 73);

        g2d.drawString("Avenida das Américas - de 3979 a 5151 - lado ímpar", 105, 13);
        g2d.drawString("Barra da Tijuca", 105, 33);
        g2d.drawString("Rio de Janeiro/RJ", 105, 53);
        g2d.drawString("22631-004", 105, 73);

        g2d.dispose();      

        File file = new File("clone.jpg");
        try {
            ImageIO.write(img, "jpg", file);

        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("clone.jpg file created.");
    }

}

My question is: What are the other options to control how a string is spaced when it's drawn? Do you have any ideas on what the original code may be doing?

Thanks!

like image 764
jbochi Avatar asked Nov 15 '22 05:11

jbochi


1 Answers

I can't really say how to do it properly in Swing, but what you are looking for is in typography called "kerning", so that attribute ought to do something similar.

like image 163
Jolta Avatar answered Dec 21 '22 06:12

Jolta