2015-07-21 2 views
10

Codice:Come correggere la qualità del testo nella grafica 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); 
    } 

} 

Risultato:

result screenshot

Come si può vedere la spaziatura tra lettere è irregolare. A volte è 1px, a volte è 2 o anche 3 pixel. Un altro problema è il punto sopra 'i' è più largo della parte inferiore.

problem details

Lo stesso testo scritto in un editor di testo sembra molto meglio. Sai come risolvere questo problema?

Il mio ambiente è Windows 8.1, Java 1.8.

+0

Forse questo ha a che fare con i caratteri vettoriali? – npinti

+0

Forse [questo] (https://today.java.net/article/2005/07/21/lcd-text-anti-aliasing-fringe) può aiutare – MadProgrammer

risposta

9

Il contesto grafico utilizza le metriche di numero intero per impostazione predefinita, ovvero l'arrotondamento viene applicato ai vettori di posizione delle forme di glifo.

è possibile passare alla metriche frazionarie utilizzando:

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

enter image description here

Come si può vedere, senza antialiasing subpixel è stato utilizzato (solo pixel antialias grigio). È possibile abilitare subpixel antialiasing per una migliore leggibilità su schermi LCD:

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

enter image description here

Ci sono 4 modalità:

  • VALUE_TEXT_ANTIALIAS_LCD_HRGB: RGB orientato orizzontalmente
  • VALUE_TEXT_ANTIALIAS_LCD_HBGR: BGR orientato orizzontalmente
  • VALUE_TEXT_ANTIALIAS_LCD_VRGB: orientato verticalmente RGB
  • VALUE_TEXT_ANTIALIAS_LCD_VBGR: orientato verticalmente BGR

non ho scoperto dove per interrogare il valore appropriato del display e orientamento corrente. Alcuni display possono essere inclinati (orizzontale/verticale) o addirittura ruotati, per cui è necessario rilevare nuovamente la modalità quando si dipinge.

EDIT

ho trovato qualcosa nel libro Filthy Rich Clients: a quanto pare, il Toolkit Java AWT in grado di fornire adeguati consigli di 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 

Sul mio sistema, questo rende il testo con metriche frazionali e LCD antialiasing HRGB, come con il codice sopra.I suggerimenti sul mio sistema sono:

  • antialiasing testo specifica abilitazione chiave: modalità HRGB antialiasing testo LCD
  • specifici Testo chiave di contrasto LCD:
+1

Grazie mille! Ha aiutato. –

+0

Il mio utilizzo principale è il video editing (con xuggler) in cui ho il controllo per impostare il tipo di immagine su 'BufferedImage' (ad esempio' BufferedImage.TYPE_3BYTE_BGR'). Quindi immagino sia indipendente dal mio sistema/monitor. Comunque, è bello sapere come ottenere questi suggerimenti. –

+0

Come è stato impostato il contrasto LCD del sistema. C'è qualche possibilità '-Dproperty = value'? –