Java可以使用子像素AA渲染半透明文本吗?

我发现虽然在Java(最新版本6u23)中渲染不透明文本虽然使用子像素AA就好了,但渲染半透明文本却没有。

子像素AA:

替代文字替代文字

只有颜色从0xFFFFFFFF变为0xBFFFFFFF的相同文本:

替代文字替代文字

正如你所看到的,半透明的文字显然是标准的AA,而不是一个干净的半透明渲染,它具有可怕的’90年代“蜘蛛”外观。

这是由于一般的子像素AA的技术限制,还是Java中的错误,或者仅仅是因为Java甚至没有尝试半透明文本,或者我错过了什么?


图形初始化

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 } 

文字渲染

 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. * 

* 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. *

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

我认为这是因为你使用GASP从字体样式中获取点数。 你尝试过使用VALUE_TEXT_ANTIALIAS_DEFAULT和VALUE_ALPHA_INTERPOLATION_DEFAULT吗? 值得一试。

http://download.oracle.com/javase/6/docs/api/java/awt/RenderingHints.html

您使用的Java版本是什么? 你不说。 但显然已经修复了Java 6更新12(J6u12)或JDK7 b43

请参见: http : //bugs.sun.com/view_bug.do?video_id = 6749060

如果您再次使用Java =或高于J6u12进行测试并仍然看到该错误,那么您可以在Sun的错误数据库中对RFE进行评论。

在Java平台中修复问题的方法是:

  1. 在Sun的BugParade上对错误报告进行投票,以提高其优先级,并等到Sun / Oracle程序员到达或
  2. 现在Java是开源的,请自行修复。 (加入ho.io/jkp5的邮件列表:-)

您想要投票或评论的Bugparade报告(如果您使用j6u12进行测试,它仍然存在)是url:ho.io/jkp2

如果你想实现一个已知的解决方法,那么即使在较旧的JRE中文本看起来也很好,这里提供了解决方法

url:ho.io/jkpy

“看起来我通过将所需的前景颜色与组件的背景颜色混合来模拟半透明效果的解决方案仍然是确保使用本机光栅化器的方法。”

祝你好运!