11

Java6でSwingGUIアプリケーションを実行すると、すべてのフォントに対して構成済みのサブピクセルアンチエイリアス設定が自動的に使用されます。結果は、標準のAAオプションよりも大幅に改善されています。

しかし、画像にペイントすると、システムのAA構成を使用するためにグラフィックスコンテキストを初期化する方法が見つかりません。すべてのユーザーに対してサブピクセル方式が機能しないため、JavaのさまざまなAAヒントを試してみるのは失われた原因です。

1つを選択して明示的にヒントを設定する代わりに、特定のグラフィックスコンテキストのシステムAA設定を継承する方法はありますか?現時点では、標準のAAが小さなフォントで与える恐ろしい結果を回避するために、GASPAAを使用する必要があります。テキストAAには何も設定せず、AAヒントもまったく設定しないようにしました。


更新2010-01-05

私はこれを固定したと思います。サブピクセルAAヒントは、AWTグラフィックスコンテキストに直接ペイントする場合にのみ尊重されるように見えます。ダブルバッファイメージにペイントすると、標準のAAが実行されます。しかし、ダブルバッファイメージをバイパスすると、サブピクセルAAが実行されます。

それ以外の場合、The_Fireの答えはSwingを使用できるJVMで機能します(ただし、J2ME JVMでは機能しません)。The_Fireの答えはAWTコンポーネントを使用して機能しないことに注意してください(新しいJLabel()の代わりにnew Label()を使用すると失敗します)。おそらく、コンポーネントがディスプレイに認識されるまでFontRenderContextを抽出できないためです。


ターゲット画像のグラフィックスコンテキストを取得するための現在のコードは、現在次のようになっています。

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

イメージを作成するコードは、基礎となるAWTコンポーネントを使用します。これは、すべてのペイントを行う背景を形成します。他のAWTコンポーネントとうまく機能するように、setFocusCycleRootを実行できる必要があるため、コンポーネントはPanelです。イメージの作成コードは次のとおりです。

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));
    }
4

4 に答える 4

7

ここで起こっているいくつかの要因があることがわかりました。

まず、イメージは基礎となるAWTコンポーネントから作成する必要があり、透明度なしで作成する必要があります。

cfg.createCompatibleImage(wid,hgt);

それ以外の

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

次に、説明のつかない理由により、LCDサブピクセルAAを使用するには、プライマリAA設定であるKEY_ANTIALIASINGをオフにする必要があります。

最後に、そして最も重要なこととして、デスクトップフォントのレンダリングヒントは、次を使用して簡単に取得できます。

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

更新2010-01-05

Java 6.26で再テストすると、テキストAAをレンダリングするために一般的なAAをオフにする必要があるという問題がようやく解決されたようです(Oracleに移行する方法... Sunがほんの数年遅れた後)。

于 2010-01-09T07:15:47.697 に答える
6

Swingを使用すると、次のような適切なテキストアンチエイリアシングヒントを取得できます。

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

私のシステムでは、これはを返しますRenderingHits.VALUE_TEXT_ANTIALIAS_LCD_HRGB

于 2009-12-22T19:27:10.670 に答える
2

java.awt.Toolkit.getDesktopProperty( "awt.font.desktophints")は、少なくとも特別なvmコマンドラインオプションがない場合、Linuxではnullのように見えます。おそらく、プラットフォームのデフォルトが何であるかを理解できないためです。 -Dawt.useSystemAAFontSettings = lcd "はそれを修復し、Graphics2Dインスタンスにヒントを設定するとサブピクセルレンダリングを有効にするようです。

于 2012-03-28T14:18:00.457 に答える
1

待って、このコードをWindows JVMで実行していますか?ClearTypeは、Swingがいくつかのネイティブコードを介して継承するMicrosoftテクノロジであると思いました(つまり、Linuxまたはその他のMicrosoft以外のプラットフォームでは使用できません)。

私はかつて、Debianで実行されるアンチエイリアスフォントでJPGを生成するサーブレットを作成しました。これは、私が使用したコードでした。

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);

オフハンドこのコードのいずれかがSwingに依存しているかどうか思い出せません(javax.swingをインポートし、サーブレットは約300行の長さなので、他の何かのために必要だと思ったかもしれません)、Googleでの簡単なチェックは次のようになりますAWT空間に正直にあります。お役に立てば幸いです。

于 2009-12-23T19:39:26.727 に答える