Come posso ereditare antialiasing del sistema impostazione per il testo pittura alle immagini off-screen come oscillazione fa?

StackOverflow https://stackoverflow.com/questions/1910964

  •  19-09-2019
  •  | 
  •  

Domanda

Quando eseguo le mie applicazioni GUI swing sotto Java 6, usano automaticamente i miei sub-pixel impostazioni anti-alias configurati per tutti i font. Il risultato è molto migliorata rispetto alle opzioni standard AA.

Ma quando dipingo a un'immagine riesco a trovare alcun modo per inizializzare il contesto grafico di utilizzare la configurazione AA del sistema. Cercando di giocare con diversi suggerimenti AA di Java è una causa persa, perché nessun metodo sub-pixel funzionerà per tutti gli utenti.

C'è un modo per ereditare le impostazioni di sistema AA per un dato contesto grafico, invece di dover scegliere uno ed esplicitamente impostare il suggerimento? Al momento devo usare GASP AA per evitare i risultati orribili che di serie AA dà con caratteri piccoli. Ho cercato di non impostare nulla per il testo AA, e che non stabilisce alcun suggerimento AA a tutti.


Aggiornamento 2010-01-05

Credo di aver appuntato questo in giù; i suggerimenti subpixel AA sembrano essere rispettata solamente quando la pittura direttamente al contesto grafico AWT; quando dipingo all'immagine un doppio tampone fa appena norma AA; ma quando bypassare l'immagine doppio buffer viene eseguita subpixel AA.

In caso contrario, la risposta di The_Fire funzionerebbe in JVM che hanno swing a disposizione (ma non J2ME JVM); Si noti che la risposta di The_Fire non funziona utilizzando un componente AWT (usando new Label () invece di nuovo JLabel () fallisce), presumibilmente perché il FontRenderContext non può essere estratto fino a quando il componente è realizzato per il display.


Il mio codice corrente per ottenere il contesto grafico per la mia immagine destinazione attualmente appare così:

try {
    if((dbImage=dctRoot.createImage(wid,hgt,1))!=null) {            // if createImage returns null or throws an exception the component is not yet displayable
        dbGraphics=(Graphics2D)dbImage.getGraphics();
        if(dctRoot.properties.getBoolean("Antialias",true)) {
            try {
                // set AA on overall
                dbGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING     ,RenderingHints.VALUE_ANTIALIAS_ON);
                // set text AA to platform/impl default
                dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
                // try to override platform/impl AA with font-specified AA (Java 6+)
                try { dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.class.getField("VALUE_TEXT_ANTIALIAS_GASP").get(null)); } catch(Throwable thr) {;} // yes, ignore exception
                }
            catch(Throwable thr) {
                dctRoot.log.println("Antialiasing not supported on this JVM ("+thr+").");
                dctRoot.setProperty("Antialias","False");           // turn off AA for subsequent painting
                }
            }
        }
    }
catch(Throwable thr) {
    dbImage=null;
    dbGraphics=null;
    }

Il codice per creare l'immagine utilizza un componente AWT sottostante, che costituisce lo sfondo su cui faccio tutta la mia pittura - il componente è un pannello, perché ho bisogno di essere in grado di fare un setFocusCycleRoot quindi gioca bene con altri AWT componenti. Il codice creare un'immagine segue:

public DctImage createImage(int wid, int hgt, float accpty) {
    GraphicsConfiguration               cfg=awtComponent.getGraphicsConfiguration();
    Image                               img=null;

    if(transparentImages) {
        //y { img=new BufferedImage(wid,hgt,BufferedImage.TYPE_INT_ARGB); }     // NB: J2ME CDC/PP 1.1 does not have the BufferedImage constructors (one day I may discover a way to create a BufferedImage via another API!!)
        try { img=cfg.createCompatibleImage(wid,hgt,Transparency.TRANSLUCENT); }// NB: J2ME CDC/PP 1.1 does not have this API, but prefer to use GraphicsConfiguration over new BufferImage(...)
        catch(NoClassDefFoundError   thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled
        catch(NoSuchMethodError      thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled
        catch(NoSuchFieldError       thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled
        }
    else {
        img=cfg.createCompatibleImage(wid,hgt);
        }

    if(accpty>0 && SET_ACCELERATION_PRIORITY!=null) {
        try { SET_ACCELERATION_PRIORITY.invoke(img,new Object[]{new Float(accpty)}); } catch(Throwable thr) {;}
        }

    return (img==null ? null : new DctImage(img));
    }
È stato utile?

Soluzione

Ho trovato ci sono stati alcuni fattori che vanno qui.

In primo luogo, l'immagine deve essere creato dal componente AWT sottostante, e deve essere creata senza trasparenza:

cfg.createCompatibleImage(wid,hgt);

anziché

cfg.createCompatibleImage(wid,hgt,Transparency.TRANSLUCENT);

In secondo luogo, per qualche motivo inspiegabile, l'impostazione AA primario, KEY_ANTIALIASING, deve essere spento per utilizzare subpixel LCD AA.

Infine, e soprattutto, il tipo di carattere del desktop rendendo suggerimenti sono facilmente recuperato utilizzando:

java.awt.Toolkit.getDesktopProperty("awt.font.desktophints")

Aggiornamento 2010-01-05

Ripetizione in Java 6.26, sembra che il problema con la necessità di impostare AA generale off per il rendering del testo AA è stato finalmente risolto (strada da percorrere Oracle ... dopo che Sun era solo un pochi anni dieci anni troppo tardi).

Altri suggerimenti

Utilizzando Altalena, sono in grado di ottenere il testo destra anti-aliasing suggerimento in questo modo:

JLabel label = new JLabel();
FontMetrics fm  = label.getFontMetrics( label.getFont() );
Object aaHintValue = fm.getFontRenderContext().getAntiAliasingHint();

Sul mio sistema restituisce RenderingHits.VALUE_TEXT_ANTIALIAS_LCD_HRGB.

java.awt.Toolkit.getDesktopProperty ( "awt.font.desktophints") sembra essere nullo su Linux, almeno senza opzioni speciali della riga di comando vm, presumibilmente perché è in grado di capire quali sono i valori di default piattaforma sono .. aggiungendo ad esempio "-Dawt.useSystemAAFontSettings = lcd" sembra curarla e consente il rendering subpixel se si imposta i suggerimenti sull'istanza Graphics2D.

Aspetta, stai eseguendo questo codice su una JVM di Windows? Ho pensato ClearType è una tecnologia Microsoft che Altalena eredita attraverso qualche codice nativo (cioè, non disponibile su Linux o altre piattaforme non Microsoft).

Una volta ho scritto un servlet che ha generato JPG con font anti-aliasing che correvano su Debian, e questo era il codice che ho usato

Font font = new Font("Komix", Font.PLAIN, 8);
Graphics2D g2;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
FontRenderContext  frc = g2.getFontRenderContext();
g2.setFont(font);
g2.setPaint(Color.black);
g2.drawString(sMessage, xOffset, yOffset);

Lì per lì non posso ricordare se qualcuno di questo codice si basa su Swing (ho importato javax.swing e il servlet è lunga circa 300 linee, quindi forse ho pensato che mi serviva per qualcos'altro), un rapido controllo su Google sembra che questo è esattamente nello spazio AWT. Speranza che aiuta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top