2015-07-21 10 views
10

Kod:Jak poprawić jakość tekstu w grafice 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); 
    } 

} 

Wynik:

result screenshot

Jak widać odstępy między literami jest nierówna. Czasami jest to 1 piksel, czasem 2 lub 3 piksele. Inną kwestią jest to, że kropka powyżej "i" jest szersza niż dolna część.

problem details

Ten sam tekst napisany w edytorze tekstu i wygląda o wiele lepiej. Czy wiesz, jak rozwiązać ten problem?

Moje środowisko to Windows 8.1, Java 1.8.

+0

Może ma to związek z czcionkami wektorowymi? – npinti

+0

Może to (https://today.java.net/article/2005/07/21/lcd-text-anti-aliasing-fringe) może pomóc – MadProgrammer

Odpowiedz

9

Kontekst graficzny domyślnie korzysta z liczb całkowitych - co oznacza, że ​​zaokrąglanie jest stosowane do wektorów lokalizacji kształtów glifów.

Możesz przełączyć się metryk ułamkowych używając:

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

enter image description here

Jak widać, nie subpiksel antyaliasingu był używany (tylko szary Wygładzanie piksel). Można umożliwić subpikseli antyaliasing dla lepszej czytelności na ekranach LCD:

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

enter image description here

Dostępne są 4 tryby:

  • VALUE_TEXT_ANTIALIAS_LCD_HRGB: poziomo RGB
  • VALUE_TEXT_ANTIALIAS_LCD_HBGR: poziomo BGR
  • VALUE_TEXT_ANTIALIAS_LCD_VRGB: pionowo RGB
  • VALUE_TEXT_ANTIALIAS_LCD_VBGR: pionowo BGR

nie znalazłem, gdzie kwerendy odpowiednią wartość aktualnego ekranu i orientacji. Niektóre wyświetlacze mogą być pochylone (poziome/pionowe) lub nawet obrócone, co wymaga ponownego wykrycia trybu podczas malowania.

EDIT

Znalazłem coś w książce Filthy Rich Clients: najwyraźniej, Java AWT Toolkit może zapewnić odpowiednich wskazówek rendering:

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 

W moim systemie, to sprawia, że ​​tekst z metryk ułamkowych i Antialiasing LCD HRGB, tak samo jak w powyższym kodzie.Podpowiedzi na moim systemie to:

  • Text-specyficzny antyaliasingu klucz umożliwiają: Tryb HRGB tekst antyaliasingu LCD
  • Text-specyficzny klucz kontrast LCD:
+1

Wielkie dzięki! Pomogło. –

+0

Moim głównym zastosowaniem jest edycja wideo (z Xuggler), gdzie mam kontrolę nad ustawianiem typu obrazu na "BufferedImage" (na przykład "BufferedImage.TYPE_3BYTE_BGR"). Sądzę więc, że jest niezależny od mojego systemu/monitora. W każdym razie, dobrze wiedzieć, jak uzyskać te wskazówki. –

+0

W jaki sposób ustawiono kontrast wyświetlacza dla całego systemu? Czy istnieje możliwość '-Dproperty = wartość'? –