Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:获取具有特定高度(以像素为单位)的字体_Java_Fonts_Graphics2d_Fontmetrics - Fatal编程技术网

Java:获取具有特定高度(以像素为单位)的字体

Java:获取具有特定高度(以像素为单位)的字体,java,fonts,graphics2d,fontmetrics,Java,Fonts,Graphics2d,Fontmetrics,使用FontMetrics很容易确定字体的渲染高度,但反过来又如何呢?如何获得适合特定高度(以像素为单位)的字体 “给我一个从上升到下降的30像素高的Verdana。” 我该如何向Java询问这个问题?我认为没有一种“直接”的方法可以通过高度找到字体;只有间接的方法。。。通过循环大小,并测试每个字体的高度,我不知道如何通过字体的实际高度(以像素为单位)来获得字体。这取决于它所使用的上下文,所以可能没有比为最佳匹配进行采样更短的方法了。从设计高度上看大小应该很快。下面是一个示例方法: public

使用
FontMetrics
很容易确定字体的渲染高度,但反过来又如何呢?如何获得适合特定高度(以像素为单位)的字体

“给我一个从上升到下降的30像素高的
Verdana
。”


我该如何向Java询问这个问题?

我认为没有一种“直接”的方法可以通过高度找到字体;只有间接的方法。。。通过循环大小,并测试每个字体的高度,我不知道如何通过字体的实际高度(以像素为单位)来获得字体。这取决于它所使用的上下文,所以可能没有比为最佳匹配进行采样更短的方法了。从设计高度上看大小应该很快。下面是一个示例方法:

public Font getFont(String name, int style, int height) {
    int size = height;
    Boolean up = null;
    while (true) {
        Font font = new Font(name, style, size);
        int testHeight = getFontMetrics(font).getHeight();
        if (testHeight < height && up != Boolean.FALSE) {
            size++;
            up = Boolean.TRUE;
        } else if (testHeight > height && up != Boolean.TRUE) {
            size--;
            up = Boolean.FALSE;
        } else {
            return font;
        }
    }
}
public字体getFont(字符串名称、int样式、int高度){
int size=高度;
布尔up=null;
while(true){
Font Font=新字体(名称、样式、大小);
int testHeight=getFontMetrics(font.getHeight();
if(testHeightheight&&up!=Boolean.TRUE){
大小--;
up=Boolean.FALSE;
}否则{
返回字体;
}
}
}

WhiteFang34的代码与以下返回特定字符串实际高度的方法结合使用非常有用。对于实时渲染,它可能有点慢,特别是对于大字体/字符串,我相信它可以进一步优化,但现在它满足了我自己的需要,并且足够快,可以在后端进程中运行

/*
 * getFontRenderedHeight
 * *************************************************************************
 * Summary: Font metrics do not give an accurate measurement of the rendered
 * font height for certain strings because the space between the ascender
 * limit and baseline is not always fully used and descenders may not be
 * present. for example the strings '0' 'a' 'f' and 'j' are all different
 * heights from top to bottom but the metrics returned are always the same.
 * If you want to place text that exactly fills a specific height, you need
 * to work out what the exact height is for the specific string. This method
 * achieves that by rendering the text and then scanning the top and bottom
 * rows until the real height of the string is found.
 */
/**
 * Calculate the actual height of rendered text for a specific string more
 * accurately than metrics when ascenders and descenders may not be present
 * <p>
 * Note: this method is probably not very efficient for repeated measurement
 * of large strings and large font sizes but it works quite effectively for
 * short strings. Consider measuring a subset of your string value. Also
 * beware of measuring symbols such as '-' and '.' the results may be
 * unexpected!
 * 
 * @param string
 *            The text to measure. You might be able to speed this process
 *            up by only measuring a single character or subset of your
 *            string i.e if you know your string ONLY contains numbers and
 *            all the numbers in the font are the same height, just pass in
 *            a single digit rather than the whole numeric string.
 * @param font
 *            The font being used. Obviously the size of the font affects
 *            the result
 * @param targetGraphicsContext
 *            The graphics context the text will actually be rendered in.
 *            This is passed in so the rendering options for anti-aliasing
 *            can be matched.
 * @return Integer - the exact actual height of the text.
 * @author Robert Heritage [mrheritage@gmail.com]
 */
public Integer getFontRenderedHeight(String string, Font font, Graphics2D targetGraphicsContext) {
    BufferedImage image;
    Graphics2D g;
    Color textColour = Color.white;

    // In the first instance; use a temporary BufferedImage object to render
    // the text and get the font metrics.
    image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
    g = image.createGraphics();
    FontMetrics metrics = g.getFontMetrics(font);
    Rectangle2D rect = metrics.getStringBounds(string, g);

    // now set up the buffered Image with a canvas size slightly larger than
    // the font metrics - this guarantees that there is at least one row of
    // black pixels at the top and the bottom
    image = new BufferedImage((int) rect.getWidth() + 1, (int) metrics.getHeight() + 2, BufferedImage.TYPE_INT_RGB);
    g = image.createGraphics();

    // take the rendering hints from the target graphics context to ensure
    // the results are accurate.
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, targetGraphicsContext.getRenderingHint(RenderingHints.KEY_ANTIALIASING));
    g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, targetGraphicsContext.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING));

    g.setColor(textColour);
    g.setFont(font);
    g.drawString(string, 0, image.getHeight());

    // scan the bottom row - descenders will be cropped initially, so the
    // text will need to be moved up (down in the co-ordinates system) to
    // fit it in the canvas if it contains any. This may need to be done a
    // few times until there is a row of black pixels at the bottom.
    boolean foundBottom, foundTop = false;
    int offset = 0;
    do {
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, image.getWidth(), image.getHeight());
        g.setColor(textColour);
        g.drawString(string, 0, image.getHeight() - offset);

        foundBottom = true;
        for (int x = 0; x < image.getWidth(); x++) {
            if (image.getRGB(x, image.getHeight() - 1) != Color.BLACK.getRGB()) {
                foundBottom = false;
            }
        }
        offset++;
    } while (!foundBottom);

    System.out.println(image.getHeight());

    // Scan the top of the image downwards one line at a time until it
    // contains a non-black pixel. This loop uses the break statement to
    // stop the while loop as soon as a non-black pixel is found, this
    // avoids the need to scan the rest of the line
    int y = 0;
    do {
        for (int x = 0; x < image.getWidth(); x++) {
            if (image.getRGB(x, y) != Color.BLACK.getRGB()) {
                foundTop = true;
                break;
            }
        }
        y++;
    } while (!foundTop);

    return image.getHeight() - y;
}
/*
*getFontRenderedHeight
* *************************************************************************
*摘要:字体度量不能准确测量渲染的字体
*某些字符串的字体高度,因为升序符号之间的间距
*限制和基线并不总是被充分使用,下降器也可能没有被完全使用
*现在。例如,字符串“0”、“f”和“j”都是不同的
*从上到下的高度,但返回的度量值始终相同。
*如果要放置精确填充特定高度的文本,则需要
*计算特定字符串的确切高度。这种方法
*通过渲染文本,然后扫描顶部和底部来实现这一点
*直到找到字符串的实际高度为止。
*/
/**
*计算特定字符串渲染文本的实际高度
*当上升者和下降者可能不存在时,比指标更准确
*
*注:这种方法对于重复测量可能不是很有效
*使用大字符串和大字体,但对于
*短字符串。考虑测量字符串值的子集。阿尔索
*当心测量符号,如“-”和“.”。结果可能是
*出乎意料!
* 
*@param字符串
*要测量的文本。你也许可以加快这个过程
*只测量一个字符或一个子集
*字符串,即如果您知道您的字符串只包含数字和
*字体中的所有数字高度相同,请输入
*单个数字,而不是整个数字字符串。
*@param字体
*正在使用的字体。很明显,字体的大小会影响
*结果
*@param targetGraphicsContext
*文本实际将在其中呈现的图形上下文。
*这是传入的,因此用于抗锯齿的渲染选项
*可以匹配。
*@return Integer-文本的确切实际高度。
*@作者Robert Heritage[mrheritage@gmail.com]
*/
公共整数GetFontRenderHeight(字符串、字体、图形2D targetGraphicsContext){
缓冲图像;
图形2dg;
颜色文本颜色=颜色。白色;
//在第一个实例中,使用临时BuffereImage对象进行渲染
//输入文本并获取字体度量。
image=newbufferedimage(1,1,BufferedImage.TYPE_INT_RGB);
g=image.createGraphics();
FontMetrics=g.getFontMetrics(字体);
Rectangle2D rect=metrics.getStringBounds(string,g);
//现在将缓冲图像设置为画布大小略大于
//字体度量-这保证至少有一行
//顶部和底部的黑色像素
image=newbufferedimage((int)rect.getWidth()+1,(int)metrics.getHeight()+2,BufferedImage.TYPE\u int\u RGB);
g=image.createGraphics();
//从目标图形上下文获取渲染提示以确保
//结果是准确的。
g、 setRenderingHint(renderingHits.KEY_抗锯齿,targetGraphicsContext.getRenderingHint(renderingHits.KEY_抗锯齿));
g、 setRenderingHint(renderingHits.KEY\u TEXT\u抗锯齿,targetGraphicsContext.getRenderingHint(renderingHits.KEY\u TEXT\u抗锯齿));
g、 设置颜色(文本颜色);
g、 setFont(字体);
g、 drawString(string,0,image.getHeight());
//扫描最下面一行-最初将裁剪下行程序,因此
//文本需要上移(坐标系中的下移)到
//如果它包含任何内容,请将其放入画布中。这可能需要在
//几次,直到底部有一行黑色像素。
布尔值foundBottom,foundTop=false;
整数偏移=0;
做{
g、 设置颜色(颜色为黑色);
g、 fillRect(0,0,image.getWidth(),image.getHeight());
g、 设置颜色(文本颜色);
g、 抽绳(字符串,0,image.getHeight()-offset);
foundBottom=true;
对于(int x=0;xdouble fontSize= 72.0 * pixelSize / Toolkit.getDefaultToolkit().getScreenResolution();
FontMetrics m= g.getFontMetrics(font); // g is your current Graphics object
double totalSize= fontSize * (m.getAscent() + m.getDescent()) / m.getAscent();