Java2D
字体
加载外部字体
package net.jadedungeon.javautil.image; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import javax.imageio.ImageIO; public class FontUtils { /** * Print fonts on image * * @param text text Str * @param font text font * @param width image width * @param height image height * @param x text x pos * @param y text y pos * @return image */ public static BufferedImage drawChars( String text, Font font, int width, int height, int x, int y) // { BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); Graphics2D gph = bimg.createGraphics(); gph.setFont(font); gph.drawString(text, x, y); return bimg; } /** * load a ttf Fonts File * * @param fontFileName full path name of ttf File * @param fontSize font size * @return font */ public static Font loadTTF(String fontFileName, float fontSize) { try (FileInputStream fi = new FileInputStream(fontFileName)) { Font dynamicFont = Font.createFont(Font.TRUETYPE_FONT, fi); Font dynamicFontPt = dynamicFont.deriveFont(fontSize); return dynamicFontPt; } catch (Exception e) { e.printStackTrace(); return new java.awt.Font("宋体", Font.PLAIN, (int) fontSize); } } public static void main(String[] args) throws Exception { Font font = loadTTF("/AaSpot.ttf", 20);// 调用 BufferedImage img = drawChars("Hello World", font, 138, 38, 10, 25); ImageIO.write(img, "jpg", new FileOutputStream(new File("/out.jpg"))); } }
字体高宽位置
java.awt.FontMetrics
这个类对文字的宽高位置有详细的介绍。
计算使用字体的一段字符串的宽与高:
/** * caculate the image size of a line of chars * * @param font using font * @param content text contenx * @return int arr [width, height] */ public static int[] calLineSize(Font font, String content) { int[] result = { 0, 0 }; FontDesignMetrics fm = FontDesignMetrics.getMetrics(font); int height = fm.getHeight(); int width = 0; for (int i = 0; i < content.length(); i++) { width += fm.charWidth(content.charAt(i)); } result[0] = width; result[1] = height; return result; }
字体基线高度
Ascent
是从基线到顶部最大的高,也可以当做一个种字体画图时最有可以点用的高度:
graphics.drawString(content, 0, metrics.getAscent());
一个有中文与英文的字符串。 中文与英文字符的宽高是不一样的:
如果想要生成一张宽高刚的图片,这样我就需要计算每一个字符的宽度,及合适的高;
import sun.font.FontDesignMetrics; import javax.imageio.ImageIO; import java.awt.*; import java.awt.font.LineMetrics; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; /** * Created by zengrenyuan on 18/5/11. */ public class ImageTest { public static void main(String[] args) throws IOException { Font font = new Font("微软雅黑", Font.BOLD, 32); String content = "你好Java!"; FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font); int width = getWordWidth(font, content);//计算图片的宽 int height = metrics.getHeight();//计算高 BufferedImage bufferedImage = new BufferedImage( width, height, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = bufferedImage.createGraphics(); graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, // RenderingHints.VALUE_TEXT_ANTIALIAS_ON); graphics.setComposite(// AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); //设置背影为白色 graphics.setColor(Color.WHITE); graphics.fillRect(0, 0, bufferedImage.getWidth(), // bufferedImage.getHeight()); graphics.setFont(font); graphics.setColor(Color.BLACK); graphics.drawString(content, 0, metrics.getAscent());//图片上写文字 graphics.dispose(); write(bufferedImage, "/data/test.png"); } public static int getWordWidth(Font font, String content) { FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font); int width = 0; for (int i = 0; i < content.length(); i++) { width += metrics.charWidth(content.charAt(i)); } return width; } public static void write(BufferedImage bufferedImage, String target) // throws IOException // { File file = new File(target); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } try (OutputStream os = new FileOutputStream(target)) { ImageIO.write(bufferedImage, "PNG", os); } } }