【问题标题】:Java: .ttf font empty, width <=0, system fonts workingJava:.ttf 字体为空,宽度 <=0,系统字体工作
【发布时间】:2014-08-25 01:39:26
【问题描述】:

我正在尝试生成给定文本大小的bufferedImage。 使用系统字体时,没有问题。 我三次检查了位置,所以这不应该是我的错误。 如果需要,我可以将字体上传到某个地方。

font = Font.createFont(Font.TRUETYPE_FONT, ttfStream);

使用 .ttf 文件时出现错误,表明其中没有数据。

font = Font.createFont(Font.TRUETYPE_FONT, ttfStream);

错误说:

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)

示例代码:

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;
        }

}

【问题讨论】:

  • 某些“TTF”字体包含 Type 1 (PostScript) 字体轮廓,而不是 TrueType 指令。您能否 (a) 检查您的字体(查看前几个字节)并 (b) 尝试使用您确定“是”真正 TrueType 的字体文件?
  • @Jongware 我在 MacOSX 上使用 Font Book 验证了字体并得到了这个:pic.flutterb.at/view/28d439.png 也许它对你有帮助?
  • 现在我也从网上查了一个ttf,实际上并没有产生这样的错误。
  • 好的,FontBook 说它是一个真正的 TTF(因此我之前的猜测无效),但它包含一些错误。据推测,这就是 Java 的字体处理失败的地方。所以你的代码似乎没有什么问题,毕竟。

标签: java fonts awt truetype fontmetrics


【解决方案1】:

问题是:新加载的字体没有嵌入大小信息。 来自 Javadoc:

这些字体以大小为 1、标识转换和默认字体特征的 Font 对象返回。然后,这些基本字体可用于通过此类中的 deriveFont 方法派生具有不同大小、样式、变换和字体特征的新 Font 对象。

http://docs.oracle.com/javase/7/docs/api/java/awt/Font.html

使用系统字体时,大小已在给定参数中设置。

使用 ttf 但情况并非如此,必须手动设置大小:

font = font.deriveFont( 20f );

还要注意它是一个浮点值,因为函数 deriveFont 被重载了一个 int 值,它将设置样式,而不是大小。

【讨论】:

    猜你喜欢
    • 2013-01-08
    • 1970-01-01
    • 2017-11-09
    • 2010-09-17
    • 2013-08-04
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 2013-01-01
    相关资源
    最近更新 更多