Tôi đang sử dụng FontMetrics.getHeight()
để nhận được chiều cao của chuỗi, nhưng nó mang lại cho tôi một giá trị sai, cắt bỏ hậu duệ của các ký tự chuỗi. Có một chức năng tốt hơn tôi có thể sử dụng?Làm thế nào để có được chiều cao chuỗi thực trong Java?
Trả lời
Các getStringBounds()
phương pháp dưới đây được dựa trên GlyphVector
cho Graphics2D
phông chữ hiện tại, trong đó hoạt động rất tốt cho một chuỗi dòng văn bản:
public class StringBoundsPanel extends JPanel
{
public StringBoundsPanel()
{
setBackground(Color.white);
setPreferredSize(new Dimension(400, 247));
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// must be called before getStringBounds()
g2.setFont(getDesiredFont());
String str = "My Text";
float x = 140, y = 128;
Rectangle bounds = getStringBounds(g2, str, x, y);
g2.setColor(Color.red);
g2.drawString(str, x, y);
g2.setColor(Color.blue);
g2.draw(bounds);
g2.dispose();
}
private Rectangle getStringBounds(Graphics2D g2, String str,
float x, float y)
{
FontRenderContext frc = g2.getFontRenderContext();
GlyphVector gv = g2.getFont().createGlyphVector(frc, str);
return gv.getPixelBounds(null, x, y);
}
private Font getDesiredFont()
{
return new Font(Font.SANS_SERIF, Font.BOLD, 28);
}
private void startUI()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception
{
final StringBoundsPanel tb = new StringBoundsPanel();
SwingUtilities.invokeAndWait(new Runnable()
{
public void run()
{
tb.startUI();
}
});
}
}
Lưu ý rằng tôi đã bỏ qua hàng nhập khẩu cho rõ ràng.
Kết quả:
FontMetrics.getAscent() và FontMetrics.getDescent() có thể thực hiện thủ thuật.
Điều gì khiến bạn nghĩ rằng nó trả về giá trị sai? Đó là nhiều hơn nữa có thể xảy ra mà mong đợi của bạn về những gì nó trả về không phù hợp với đặc điểm kỹ thuật. Lưu ý rằng nó hoàn toàn tốt nếu một số glyph trong Font đi qua hoặc dưới các giá trị đó.
getMaxDescent()
và getMaxAscent()
sẽ cho bạn biết giá trị cực đại tuyệt đối của các trường đó cho bất kỳ hình tượng nào trong Phông chữ.
Nếu bạn muốn biết số liệu cho một Chuỗi cụ thể, thì bạn chắc chắn muốn gọi getLineMetrics()
.
getHeight()
không thể cắt bỏ phần tử con của chuỗi, chỉ vẽ chuỗi có thể làm điều đó. Bạn đang sử dụng chiều cao được trả về từ getHeight
để vẽ chuỗi bằng cách nào đó và có khả năng bạn đang lạm dụng chiều cao. Ví dụ: nếu bạn định vị điểm bắt đầu của chuỗi ở cuối hộp là getHeight() cao, thì đường cơ sở của văn bản của bạn sẽ nằm ở cạnh dưới cùng của hộp và rất có thể con cháu sẽ bị cắt bớt.
Hình học văn bản là một chủ đề phức tạp, được truyền với các tạo phẩm kỳ lạ trong lịch sử. Như những người khác đã đề xuất, hãy sử dụng getAscent
và getDescent
để cố định vị trí đường cơ sở chính xác trong hộp của bạn.
Gần đây tôi đã viết đoạn code dưới đây như tôi cần điểm ảnh đo hoàn hảo chiều cao cho các phạm vi cụ thể của phông chữ (ví dụ: tất cả các nhân vật thấp hơn, hoặc tất cả các số).
Nếu bạn cần mã nhanh hơn (tôi có cho vòng) Tôi khuyên bạn nên chạy nó một lần lúc khởi động để nhận tất cả các giá trị (ví dụ từ 1 đến 100) trong một mảng và sau đó sử dụng mảng thay thế. Mã này về cơ bản vẽ tất cả các ký tự từ chuỗi đầu vào tại cùng một vị trí chồng chéo trên một bitmap 250x250 (tăng hoặc giảm nếu cần), nó bắt đầu tìm kiếm pixel từ trên xuống, sau đó từ dưới cùng, sau đó nó trả về chiều cao tối đa được tìm thấy . Nó hoạt động với các chuỗi bình thường ngay cả khi nó được thiết kế cho các phạm vi ký tự. Điều này có nghĩa là có một loại dự phòng khi đánh giá các chuỗi thông thường khi một số ký tự lặp lại. Vì vậy, nếu chuỗi imput của bạn vượt quá số bảng chữ cái (26), hãy sử dụng như imput 'tRange': "abcd ... z" và các ký tự khác có thể được sử dụng. Nó nhanh hơn.
Hy vọng điều đó sẽ hữu ích.
public int getFontPixelHeight(float inSize, Paint sourcePaint, String tRange)
{
// It is assumed that the font is already set in the sourcePaint
int bW = 250, bH = 250; // bitmap's width and height
int firstContact = -1, lastContact = -2; // Used when scanning the pixel rows. Initial values are set so that if no pixels found, the returned result is zero.
int tX = (int)(bW - inSize)/2, tY = (int)(bH - inSize)/2; // Used for a rough centering of the displayed characters
int tSum = 0;
// Preserve the original paint attributes
float oldSize = sourcePaint.getTextSize();
int oldColor = sourcePaint.getColor();
// Set the size/color
sourcePaint.setTextSize(inSize); sourcePaint.setColor(Color.WHITE);
// Create the temporary bitmap/canvas
Bitmap.Config bConf = Bitmap.Config.ARGB_8888;
Bitmap hld = Bitmap.createBitmap(250, 250, bConf);
Canvas canv = new Canvas(hld);
for (int i = 0; i < bH; i++)
{
for (int j = 0; j < bW; j++)
{
hld.setPixel(j, i, 0); // Zero all pixel values. This might seem redundant, but I am not quite sure that creating a blank bitmap means the pixel color value is indeed zero, and I need them to be zero so the addition performed below is correct.
}
}
// Display all characters overlapping at the same position
for (int i = 0; i < tRange.length(); i++)
{
canv.drawText("" + tRange.charAt(i), tX, tY, sourcePaint);
}
for (int i = 0; i < bH; i++)
{
for (int j = 0; j < bW; j++)
{
tSum = tSum + hld.getPixel(j, i);
}
if (tSum > 0) // If we found at least a pixel, save row index and exit loop
{
firstContact = i;
tSum = 0; // Reset
break;
}
}
for (int i = bH - 1; i > 0 ; i--)
{
for (int j = 0; j < bW; j++)
{
tSum = tSum + hld.getPixel(j, i);
}
if (tSum > 0) // If we found at least a pixel, save row index and exit loop
{
lastContact = i;
break;
}
}
// Restore the initial attributes, just in case the paint was passed byRef somehow
sourcePaint.setTextSize(oldSize);
sourcePaint.setColor(oldColor);
return lastContact - firstContact + 1;
}
- 1. Làm thế nào để có được chiều cao thực sự của TextBox?
- 2. Làm thế nào để có được chiều cao và chiều rộng thiết bị khi chạy?
- 3. Làm thế nào để có được chiều rộng và chiều cao của trang PDF?
- 4. Làm thế nào tôi có thể nhận được chiều cao của một chuỗi cho trước?
- 5. Làm thế nào để thay đổi chiều cao băng động?
- 6. Làm thế nào để có chiều rộng/chiều cao mới của bố cục gốc trong onConfigurationChanged?
- 7. javascript/jquery: làm thế nào để có được chiều cao cửa sổ bên trong?
- 8. Làm thế nào để có được chiều cao hàng đúng trong Qt cho đối tượng QTableView?
- 9. Làm thế nào tôi có thể nhận được chiều rộng và chiều cao
- 10. Làm thế nào để có chiều cao của bảng html = chiều cao của div mẹ khi chiều cao của div không được đặt
- 11. Làm thế nào để bạn có được chiều rộng và chiều cao của ảnh SVG trong PHP?
- 12. Làm thế nào để có được chiều cao của một nhịp?
- 13. SDK iPhone: Làm cách nào để đo chiều rộng và chiều cao của chuỗi bằng Quartz?
- 14. Làm thế nào để có được những 'chiều cao' của màn hình sử dụng jquery
- 15. GAE: Làm thế nào để có được chiều cao blob-image
- 16. Làm cách nào để vẽ một chuỗi được căn giữa theo chiều dọc trong Java?
- 17. Làm thế nào để có được chiều dài của chuỗi dài nhất trong một mảng
- 18. Làm thế nào để nhanh chóng có được chiều rộng và chiều cao của TextView sử dụng Paint.getTextBounds()?
- 19. Làm thế nào để EditText Box Chiều cao Mở rộng
- 20. Làm thế nào để bạn có được chiều rộng màn hình trong java?
- 21. jQuery có được chiều cao từ trên
- 22. Làm thế nào để kiểm soát chiều cao biên giới?
- 23. Làm thế nào để tăng chiều cao của highchart?
- 24. làm thế nào để thiết lập mục ListView chiều cao
- 25. Làm cách nào để có chiều rộng chuỗi trong Libgdx?
- 26. Làm thế nào để trích xuất chiều rộng và chiều cao của đường viền trong javacv?
- 27. Làm thế nào để có được chiều rộng và chiều cao của một div với extjs 4?
- 28. Tại sao trình duyệt trả về chuỗi trống trên style.height? Làm thế nào để có được chiều cao thực tế của một phần tử?
- 29. Làm thế nào để mạnh mẽ chiều cao dòng trong css, không có streches?
- 30. vẽ dữ liệu chiều cao trong java
@nierito Câu trả lời hay và tuyệt vời! Dựa trên những gì bạn đã nói, tôi đã cố gắng rút ngắn mã của bạn (giả sử rằng đã xác định một 'Font' và nhận' FontMetrics' từ nó.) Nó hoạt động khá tốt. 'font.createGlyphVector (fontMetrics.getFontRenderContext(), text) .getVisualBounds(). getHeight(); ' –
Làm thế nào để sử dụng GlyphVector.getPixelBounds so sánh với Font.getStringBounds và TextLayout.getBounds? Có một lợi thế lớn cho mã phức tạp hơn? Trong một thử nghiệm đơn giản, tôi thấy rằng phương thức Phông chữ đã báo cáo chiều cao so với hai phương pháp kia. Tôi thích nó và TextLayout không yêu cầu điểm x và y. – jla
là 8 năm, nhưng khi tôi sử dụng g2d.scale (x, x); nó không thể hiển thị đúng! – yelliver