2015-07-21 42 views
10

代碼:如何修復Java圖形中的文本質量?

import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 

import javax.swing.JFrame; 

public class TextRectangle extends JFrame { 

    private static final long serialVersionUID = 1L; 

    public static void main(String[] a) { 
     TextRectangle f = new TextRectangle(); 
     f.setSize(300, 300); 
     f.setVisible(true); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    public void paint(Graphics g) { 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setRenderingHint(
      RenderingHints.KEY_TEXT_ANTIALIASING, 
      RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
     g2d.setRenderingHint(
      RenderingHints.KEY_RENDERING, 
      RenderingHints.VALUE_RENDER_QUALITY); 

     g2d.setColor(Color.WHITE); 
     g2d.fillRect(0, 0, getWidth(), getHeight()); 

     g2d.setColor(Color.BLACK); 
     g2d.setFont(new Font("Calibri", Font.BOLD, 18)); 
     g2d.drawString("Why does this text look so ugly?", 30, 150); 
    } 

} 

結果:

result screenshot

正如你所看到的字間距是不均勻的。有時候是1px,有時候是2甚至3個像素。另一個問題是'i'上面的點比底部寬。

problem details

寫在文本編輯器中相同的文字看起來好多了。你知道如何解決這個問題嗎?

我的環境是Windows 8.1,Java 1.8。

+0

這也許必須做與矢量字體? – npinti

+0

也許[this](https://today.java.net/article/2005/07/21/lcd-text-anti-aliasing-fringe)可以提供幫助 – MadProgrammer

回答

9

默認情況下圖形上下文使用整數度量 - 這意味着舍入應用於字形形狀的位置矢量。

可以使用切換到小數規格

g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, 
    RenderingHints.VALUE_FRACTIONALMETRICS_ON); 

enter image description here

正如你可以看到,不使用子像素抗鋸齒(僅灰抗混疊像素)。您可以在LCD屏幕上啓用子像素抗鋸齒更好的可讀性:

g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
    RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); 

enter image description here

有4種模式:

  • VALUE_TEXT_ANTIALIAS_LCD_HRGB:水平方向的RGB
  • VALUE_TEXT_ANTIALIAS_LCD_HBGR:水平方向BGR
  • VALUE_TEXT_ANTIALIAS_LCD_VRGB:垂直定向的RGB
  • VALUE_TEXT_ANTIALIAS_LCD_VBGR:垂直定向BGR

我還沒有發現在哪裏查詢當前顯示和方向的適當的值。有些顯示器可以傾斜(橫向/縱向)甚至旋轉,需要在繪畫時重新檢測模式。

編輯

我發現在Filthy Rich Clients書的內容:顯然,在Java AWT工具包可以提供適當的呈現提示:

Map<?, ?> desktopHints = 
    (Map<?, ?>) Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"); 

Graphics2D g2d = (Graphics2D) g; 
if (desktopHints != null) { 
    g2d.setRenderingHints(desktopHints); 
} 
// no need to set more rendering hints 

在我的系統,這使它與小數規格和文本LCD HRGB抗鋸齒,與上面的代碼相同。我的系統上的提示是:

  • 文本的特定抗鋸齒啓用鍵:LCD HRGB抗鋸齒文本模式
  • 特定文本LCD對比度鍵:
+1

非常感謝!它有幫助。 –

+0

我的主要用法是視頻編輯(帶有xuggler),我可以在其中控制在「BufferedImage」上設置圖像類型(例如'BufferedImage.TYPE_3BYTE_BGR')。所以我想它與我的系統/顯示器無關。無論如何,很高興知道如何獲得這些提示。 –

+0

您是如何設置系統寬屏LCD對比度的。是否有一些'-Dproperty = value'的可能性? –