可以很容易地确定使用FontMetrics
字体的呈现高度,但对于周围的其他方式?我怎样才能获得一个字体,将适合像素的特定高度?的Java:获取字体与特定的高度以像素为单位
“给我
Verdana
从上行到下行30个像素的高度。”
我怎么问Java的这种?
可以很容易地确定使用FontMetrics
字体的呈现高度,但对于周围的其他方式?我怎样才能获得一个字体,将适合像素的特定高度?的Java:获取字体与特定的高度以像素为单位
“给我
Verdana
从上行到下行30个像素的高度。”
我怎么问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;
}
}
}
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 [[email protected]]
*/
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;
}
我知道这是一个很古老的问题,但有人可能会觉得这仍然是:
要计算需要一定的像素高度的点,你应该能够使用如下:
double fontSize= pixelSize * Toolkit.getDefaultToolkit().getScreenResolution()/72.0;
我还没有测试过这个,但它似乎适用于我用过的显示器。如果我发现它不起作用的情况,我会报告回来。
对于我已经使用此系统标准字体,此设置一个大写字母(即,上升)所提供的像素尺寸的高度。
FontMetrics m= g.getFontMetrics(font); // g is your current Graphics object
double totalSize= fontSize * (m.getAscent() + m.getDescent())/m.getAscent();
当然,一些特定的字母实际像素高度将取决于字母和字体:如果您需要设置上升+下降到像素的大小,你可以使用FontMetrics修正值使用,所以如果你想确保你的“H”是一些确切的像素高,你可能仍然想使用其他答案中提到的反复试验方法。请记住,如果您使用这些方法来获取要显示的每个特定文本的大小(如@Bob建议的那样),则最终可能会在屏幕上出现随机字体大小混乱,其中像“ace “将比”标签“有更大的字母。为了避免这种情况,我会选择一个特定的字母或字母序列(“T”或“Tg”或其他),然后将其固定到像素高度一次,然后使用您从该处随处获得的字体大小。
谢谢澄清这一点...我刚刚检查和一个字体的大小18f似乎是我的30“显示器运行从对接约1/4”端口......并且当我卸下笔记本电脑并使用其更小的屏幕时,也会出现1/4“......一个启示! – 2016-05-09 14:55:19
只是好奇 - 你想做什么? – kleopatra 2011-04-29 12:09:02
试图优化文本布局,以最大限度地利用可用的显示尺寸 – 2011-04-29 13:48:56