Ich habe festgestellt, dass beim Rendern von undurchsichtigem Text in Java (neueste Version 6u23) Sub-Pixel AA nur gut verwendet, Rendering transluzenten Text nicht.Kann Java transparenten Text mit Subpixel AA rendern?
Sub-Pixel-AA:
Der gleiche Text, für die nur die Farbe von 0xFFFFFFFF zu 0xBFFFFFFF geändert wurde:
Wie Sie sehen können, Der transluzente Text ist klar Standard-AA und anstatt eines sauberen, durchscheinenden Renderings, hat er dieses schreckliche "spidery" Aussehen der 90er Jahre.
Liegt das an einer technischen Einschränkung für Subpixel AA im Allgemeinen oder an einem Bug in Java, oder nur weil Java nicht einmal nach transparentem Text sucht, oder habe ich etwas verpasst?
Graphics Initialisierung
dbGraphics=(Graphics2D)dbImage.getGraphics();
if(dctRoot.properties.getBoolean("Antialias",true)) {
try {
Map hnts=(Map)(dctRoot.awtComponent.getToolkit().getDesktopProperty("awt.font.desktophints"));
// SET AA ON OVERALL (NOTE: GENERAL AA MUST BE OFF FOR SUBPIXEL AA TO BE HONORED - TEXT WIDGETS MUST DO THIS THEMSELVES)
dbGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
if(hnts!=null) {
// SET FONT RENDERING HINTS FROM DESKTOP
dbGraphics.addRenderingHints(hnts);
}
else {
try {
// SET TEXT AA TO FONT-SPECIFIED GASP AA (JAVA 6+)
dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.class.getField("VALUE_TEXT_ANTIALIAS_GASP").get(null));
}
catch(Throwable thr3) {
// SET TEXT AA TO DEFAULT
dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
}
}
catch(Throwable thr) {
dctRoot.log.println("Antialiasing not supported on this JVM ("+thr+").");
dctRoot.setProperty("Antialias","False"); // turn off AA for subsequent painting
}
}
else {
try {
dbGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
catch(Throwable thr) {;} // ignore exception
}
Text Rendering
Object oaa=disableGeneralAA(gc);
...
gc.drawString(tl,xx,(ty+(xa*met.getHeight())));
restoreGeneralAA(gc,oaa);
...
static private volatile boolean hasRenderingHints=true;
// *****************************************************************************
// STATIC INIT & MAIN
// *****************************************************************************
// *****************************************************************************
// STATIC METHODS
// *****************************************************************************
/**
* Disable the general anti-aliasing rendering hint, returning whether the old value was RenderingHints.VALUE_ANTIALIAS_ON.
* <p>
* This method is needed for text rendering due to a bug in AWT; as of Java 6_20 when general AA is on text is not rendered using subpixel
* AA, so general AA has to be turned off before rendering text and turned back on when done. This method abstracts that work and deals
* with the possibility that the JVM does not support rendering hints, such as is the case with JME JVMs.
*/
static public Object disableGeneralAA(Graphics2D gc) {
Object old=null;
if(hasRenderingHints) {
try {
old=gc.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
}
catch(NoClassDefFoundError thr) { hasRenderingHints=false; }
catch(NoSuchFieldError thr) { hasRenderingHints=false; }
catch(NoSuchMethodError thr) { hasRenderingHints=false; }
}
return old;
}
/**
* Disable the general anti-aliasing rendering hint, returning whether the old value was RenderingHints.VALUE_ANTIALIAS_ON.
* <p>
* This method is needed for text rendering due to a bug in AWT; as of Java 6_20 when general AA is on text is not rendered using subpixel
* AA, so general AA has to be turned off before rendering text and turned back on when done. This method abstracts that work and deals
* with the possibility that the JVM does not support rendering hints, such as is the case with JME JVMs.
*/
static public void restoreGeneralAA(Graphics2D gc, Object val) {
Object old=null;
if(hasRenderingHints && val!=null) {
try { gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,val); }
catch(NoClassDefFoundError thr) { hasRenderingHints=false; }
catch(NoSuchFieldError thr) { hasRenderingHints=false; }
catch(NoSuchMethodError thr) { hasRenderingHints=false; }
}
}
Haben Sie versucht, den Antialias-Text in ein 'BufferedImage' zu übertragen und dann mit einem' AlphaComposite' das Bild transparent auf den Bildschirm zu zeichnen? (Es wird leider langsamer.) – finnw
@finnw: Alle Bilder werden auf einem Offscreen BufferedImage gemacht, und dieses Bild wird in den zugrundeliegenden Bildschirmgrafik-Kontext auf jedem 'paint (Graphics agc)' mit einem einfachen 'gc.drawImage' kopiert . Ich erwarte, dass das Bild im Offscreen-Puffer das endgültige Bild darstellt. Ich mache viel durchsichtiges Malen, und das einzige Problem ist, dass Text-Rendering Standard-AA zu sein scheint, wenn die Textfarbe durchscheinend ist. –
Sieht so aus, als ob dies eine Zeit lang ein Problem gewesen wäre http://forums.java.net/node/676951 – z5h