首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java能用亚像素AA渲染半透明文本吗?

Java能用亚像素AA渲染半透明文本吗?
EN

Stack Overflow用户
提问于 2010-12-22 19:40:42
回答 3查看 1.1K关注 0票数 10

我发现在Java (最新版本6u23)中呈现不透明文本时,使用亚像素AA只是很好,而渲染半透明文本则不是这样。

亚像素AA:

只有颜色从0xFFFFFFF更改为0xBFFFFFF的同一文本:

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

这是因为一般亚像素AA的技术限制,还是Java中的一个bug,或者仅仅因为Java甚至没有尝试半透明文本,还是我遗漏了什么?

图形初始化

代码语言:javascript
复制
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
    }

文本呈现

代码语言:javascript
复制
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; }
        }
    }
EN

回答 3

Stack Overflow用户

发布于 2011-01-13 09:15:36

将文本呈现给透明的背景似乎不(完全)支持,从这些bugreports可以看出:

  • http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6728834
  • http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6749060
  • http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6749069
票数 1
EN

Stack Overflow用户

发布于 2010-12-28 05:03:04

我认为这是因为你的使用喘息,这从字体风格的要点。你试过使用VALUE_TEXT_ANTIALIAS_DEFAULT和VALUE_ALPHA_INTERPOLATION_DEFAULT吗?值得一试。

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

票数 0
EN

Stack Overflow用户

发布于 2011-01-15 10:38:22

您使用的是什么Java版本?你没说。但是很明显,这在Java6更新12 (J6u12)或JDK7 b43中已经解决了。

见此处:http://bugs.sun.com/view_bug.do?bug_id=6749060

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

在Java平台中解决问题的方法是:

  1. 在Sun‘s BugParade上对bug报告进行投票,以提高它的优先级,等到Sun/Oracle程序员找到它或
  2. (既然Java是开源的),就自己修复它。(加入ho.io/jkp5 5 :-)

的邮件列表

您想要投票或发表评论的Bugparade报告在这里(如果您用j6u12测试,它仍然存在)是url: ho.io/jkp2 2。

如果您想实现一个已知的工作-这样,即使在旧的JREs中,文本看起来也不错-这里提供了一个工作方法。

网址: ho.io/jkpy

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

祝好运!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4513030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档