2011-04-29 14 views
5

यह दूसरी तरह के आसपास के बारे में FontMetrics का उपयोग कर एक फ़ॉन्ट का गाया ऊंचाई है, लेकिन क्या यह निर्धारित करने के लिए आसान है में एक विशिष्ट ऊंचाई के साथ एक फ़ॉन्ट रही है? मैं एक फ़ॉन्ट कैसे प्राप्त कर सकता हूं जो पिक्सल में एक विशिष्ट ऊंचाई में फिट होगा?जावा: पिक्सल

"मुझे Verdana एक आकार में दें जो 30 पिक्सेल से ascender से descender तक है।"

मैं इस के लिए जावा पूछते हैं?

+0

बस उत्सुक - आप क्या करने की कोशिश कर रहे हैं? – kleopatra

+0

उपलब्ध डिस्प्ले आकार का सर्वोत्तम उपयोग करने के लिए टेक्स्ट लेआउट को अनुकूलित करने का प्रयास –

उत्तर

5

जेन,

मैं वहाँ एक "प्रत्यक्ष" जिस तरह से ऊंचाई से एक फ़ॉन्ट खोजने के लिए नहीं लगता है; केवल एक अप्रत्यक्ष तरीका ... आकार के माध्यम से लूपिंग करके, और प्रत्येक की ऊंचाई का परीक्षण < = आवश्यक ऊंचाई है।

आप उन के माध्यम से इस बार, बस पाश कर रहे हैं ... यदि आप "मक्खी पर" यह कर दिया है तो एक द्विआधारी खोज करते हैं, यह जल्दी हो जाएगा।

चीयर्स। कीथ।

5

मैं एक तरह से पिक्सल में अपने वास्तविक ऊंचाई से एक फ़ॉन्ट प्राप्त करने के बारे में पता नहीं कर रहा हूँ। यह उस संदर्भ पर निर्भर करता है जिसका उपयोग इस प्रकार किया जाता है, इसलिए संभवतः सर्वश्रेष्ठ मिलान के नमूने के मुकाबले कोई छोटा रास्ता नहीं है। यह डिजाइन की ऊंचाई से ऊपर या नीचे आकार देखने के लिए बहुत तेज़ होना चाहिए।

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; 
     } 
    } 
} 
1

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; 
} 
5

मैं जानता हूँ कि यह एक बहुत पुरानी सवाल है, लेकिन किसी को अभी भी यह हो सकता है:

The font height in Java (and many other places) is given in "typographic points", which are defined as roughly 1/72nd of an inch.

अंक एक निश्चित पिक्सेल ऊंचाई के लिए आवश्यक गणना करने के लिए, आप का उपयोग करने के लिए सक्षम होना चाहिए निम्नलिखित:

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 मूल्य सही कर सकते हैं उपयोग किया जाता है, इसलिए यदि आप यह सुनिश्चित करना चाहते हैं कि आपका "एच" कुछ सटीक पिक्सेल लंबा है, तो आप अभी भी अन्य उत्तरों में उल्लिखित परीक्षण-और-त्रुटि विधियों का उपयोग करना चाहेंगे। बस ध्यान रखें कि यदि आप प्रत्येक विशिष्ट पाठ के आकार को प्राप्त करने के लिए इन विधियों का उपयोग करते हैं (जैसे @ बॉब सुझाव दिया गया है), तो आप अपनी स्क्रीन पर एक यादृच्छिक फ़ॉन्ट-आकार-गड़बड़ी के साथ समाप्त हो सकते हैं, जहां "ऐस" "टैग" की तुलना में बहुत अधिक अक्षर होंगे। इससे बचने के लिए, मैं एक विशिष्ट अक्षर या अक्षर अनुक्रम ("टी" या "टीजी" या कुछ) चुनता हूं और उसे एक बार अपनी पिक्सेल ऊंचाई पर ठीक करता हूं और फिर उस स्थान से प्राप्त फ़ॉन्ट आकार का उपयोग करता हूं।

+0

इस स्पष्टीकरण के लिए धन्यवाद ... मैंने अभी जांच की है और आकार का फ़ॉन्ट 18f डॉकिंग से चलने वाले मेरे 1/4 "मॉनीटर पर 1/4" लगता है बंदरगाह ... और यह भी 1/4 दिखाई देता है "जब मैं अपने लैपटॉप को अनदेखा करता हूं और अपनी छोटी स्क्रीन का उपयोग करता हूं ... एक रहस्योद्घाटन! –

संबंधित मुद्दे