[英]How to get the precise bounding box of a character in Java
I am trying to get the precise bounding box of a character in Java.我正在尝试获取 Java 中字符的精确边界框。 Is it normal that if I perform (for example in a Swing component):如果我执行(例如在 Swing 组件中)是否正常:
public class MyFrame extends JFrame {
public MyFrame() {
super();
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
private void computeWidth() {
String character = "A";
JLabel label = new JLabel();
Font font = label.getFont();
font = font.deriveFont(12);
// method with FontMetrics
FontMetrics fontMetrics = this.getFontMetrics(font);
Rectangle2D recWithMetrics = fontMetrics.getStringBounds(character, this.getGraphics());
System.out.println("recWithMetrics : " + recWithMetrics);
// method with GlyphVector outline
FontRenderContext ctx = new FontRenderContext(new AffineTransform(), true, true);
GlyphVector gv = font.createGlyphVector(ctx, character);
Rectangle2D recWithOutline = gv.getOutline().getBounds2D();
System.out.println("recWithOutline : " + recWithOutline);
}
public static void main(String[] args) {
MyFrame frame = new MyFrame();
frame.computeWidth();
frame.setVisible(true);
}
}
recWithMetrics
and recWithOutline
don't have the same values at all, is it due to the fact that the method using the FontMetrics
includes the advance? recWithMetrics
和recWithOutline
根本没有相同的值,是因为使用FontMetrics
的方法包含了提前吗?
I've found it 'simpler' to get the Shape
of the text and work with that.我发现获取文本的Shape
并使用它“更简单”。
import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class TextBoundingBox {
private JComponent ui = null;
public static String string = "Red outline shows bounds of text";
public static Font font = new Font(Font.SANS_SERIF, Font.BOLD, 36);
TextBoundingBox() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
ui.add(new JLabel(new ImageIcon(getImage())));
}
private static BufferedImage getImage() {
Shape shape = getShapeOfText(font, string);
Rectangle2D boundsRectangle = shape.getBounds2D();
double w = boundsRectangle.getWidth();
double h = boundsRectangle.getHeight();
int wBig = (int) (w * 1.1);
int hBig = (int) (h * 2);
BufferedImage bi = new BufferedImage(
wBig, hBig, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, wBig, hBig);
g.setColor(Color.BLACK);
g.fill(moveShapeToCenter(shape, wBig, hBig));
g.setColor(Color.RED);
g.draw(moveShapeToCenter(boundsRectangle, wBig, hBig));
g.dispose();
return bi;
}
public static Shape moveShapeToCenter(Shape shape, int w, int h) {
Rectangle2D b = shape.getBounds2D();
double xOff = -b.getX() + ((w - b.getWidth()) / 2d);
double yOff = -b.getY() + ((h - b.getHeight()) / 2d);
AffineTransform move = AffineTransform.getTranslateInstance(xOff, yOff);
return move.createTransformedShape(shape);
}
public static Shape getShapeOfText(Font font, String msg) {
BufferedImage bi = new BufferedImage(
1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
FontRenderContext frc = g.getFontRenderContext();
GlyphVector gv = font.createGlyphVector(frc, msg);
return gv.getOutline();
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = () -> {
TextBoundingBox o = new TextBoundingBox();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.