如何在Java中获得字符的精确边界框
我试图在Java中获得字符的精确边界框。如果我在Swing组件中执行以下操作,是否正常:如何在Java中获得字符的精确边界框,java,string,swing,Java,String,Swing,我试图在Java中获得字符的精确边界框。如果我在Swing组件中执行以下操作,是否正常: public class MyFrame extends JFrame { public MyFrame() { super(); this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); } private void computeWidth() { String character = "A
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和recWithOutline的值根本不相同,这是因为使用FontMetrics的方法包括advance吗?我发现获得文本的形状并使用它“更简单”
我发现获得文本的形状并处理它“更简单”
这是因为使用FontMetrics的方法包括advance吗为什么不显示FontMetrics中的advance值,看看这是否是差异。你是对的,我会检查!!这是因为使用FontMetrics的方法包括advance吗为什么不显示FontMetrics中的advance值,看看这是否是差异。你是对的,我会检查!!因此,在我的测试程序中,第二种情况是使用GlyphVector。我在您的示例中看到大纲是完美的。老实说,我没有仔细查看您的代码。我只知道获取文本的形状对于进行进一步处理非常可靠。这正是我需要的信息。谢谢因此,在我的测试程序中,第二种情况是使用GlyphVector。我在您的示例中看到大纲是完美的。老实说,我没有仔细查看您的代码。我只知道获取文本的形状对于进行进一步处理非常可靠。这正是我需要的信息。谢谢
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);
}
}