I am trying to generate a bufferedImage
of the size of the given text.
When using a system font, there is no problem.
I tripple checked the location, so that should not be my mistake.
I can upload the font somewhere if needed.
font = Font.createFont(Font.TRUETYPE_FONT, ttfStream);
When using a .ttf file I get errors, indicating that there is no data in there.
font = Font.createFont(Font.TRUETYPE_FONT, ttfStream);
The Error says:
Exception in thread "main" java.lang.IllegalArgumentException: Width (0) and height (1) cannot be <= 0
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1016)
at java.awt.image.BufferedImage.<init>(BufferedImage.java:340)
at ErrorExample.stringToBufferedImage(Untitled.java:64)
at ErrorExample.main(Untitled.java:35)
Example code:
class ErrorExample {
static boolean dontwork = true;
public static void main(String[] args) throws IOException, FontFormatException{
InputStream ttfStream = new BufferedInputStream(new FileInputStream("/test/monofont.ttf"));
Font font;
if(dontwork == true){ //here the fun seems to be.
font = Font.createFont(Font.TRUETYPE_FONT, ttfStream);
}else{
font = new Font( "Verdana", Font.BOLD, 20 );
}
BufferedImage img = stringToBufferedImage(font, "sdf");
System.out.println("Done.");
}
/**
* Modiefied from http://stackoverflow.com/a/17301696/3423324
* @param font
*/
public static BufferedImage stringToBufferedImage(Font f, String s) {
//First, we have to calculate the string's width and height
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
Graphics g = img.getGraphics();
//Set the font to be used when drawing the string
//f = new Font("Tahoma", Font.PLAIN, 48);
g.setFont(f);
//Get the string visual bounds
FontRenderContext frc = g.getFontMetrics().getFontRenderContext();
Rectangle2D rect = f.getStringBounds(s, frc);
//Release resources
g.dispose();
//Then, we have to draw the string on the final image
//Create a new image where to print the character
img = new BufferedImage((int) Math.ceil(rect.getWidth()), (int) Math.ceil(rect.getHeight()), BufferedImage.TYPE_INT_ARGB);
//Graphics2D g2d = img.;
//g2d.setColor(Color.black); // Otherwise the text would be white
g = img.getGraphics();
Graphics2D g2d = (Graphics2D) g;
g.setColor(Color.black); //Otherwise the text would be white
g2d.setColor(Color.black); //Otherwise the text would be white
g2d.setFont(f);
//Calculate x and y for that string
FontMetrics fm = g.getFontMetrics();
int x = 0;
int y = fm.getAscent(); //getAscent() = baseline
g2d.drawString(s, x, y);
//Release resources
g.dispose();
//Return the image
return img;
}
}
The Problem was: A newly loaded font has no size information embedded. From Javadoc:
These font faces are returned as Font objects with a size of 1, identity transform and default font features. These base fonts can then be used to derive new Font objects with varying sizes, styles, transforms and font features via the
deriveFont
methods in this class.
http://docs.oracle.com/javase/7/docs/api/java/awt/Font.html
While using system fonts the size is already set in the given arguments.
Using ttf however this is not the case, and the size must be set manually:
font = font.deriveFont( 20f );
Also note it it's a float value, because the function deriveFont
is overloaded with an int
value, which will set a style, not the size.