Java可以使用子像素AA渲染半透明文本吗?
我发现,虽然在 Java(最新版本 6u23)中渲染不透明文本可以使用子像素 AA,但渲染半透明文本却不能。
子像素 AA:
仅颜色从 0xFFFFFFFF 更改为 0xBFFFFFFF 的相同文本:
< img src="https://i.sstatic.net/F3rlJ.gif" alt="alt text">
正如你所看到的,半透明文本显然是标准的 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.
* <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; }
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
似乎不(完全)支持将文本渲染到透明背景,从这些错误报告中可以看出:
It seems rendering text to a transparant background is not (fully) supported, as can be seen from these bugreports:
我认为这是因为你使用了 GASP,它从字体样式中获取了点。您是否尝试过使用VALUE_TEXT_ANTIALIAS_DEFAULT和VALUE_ALPHA_INTERPOLATION_DEFAULT?值得一试。
http://download.oracle.com/javase/6 /docs/api/java/awt/RenderingHints.html
I think its because your using GASP which takes the points from the font style. have you tried using VALUE_TEXT_ANTIALIAS_DEFAULT and VALUE_ALPHA_INTERPOLATION_DEFAULT? it's worth a shot.
http://download.oracle.com/javase/6/docs/api/java/awt/RenderingHints.html
您使用什么 Java 版本?你不说。但显然这个问题已在 Java 6 update 12 (J6u12) 或 JDK7 b43 中得到修复
请参见此处:
https://bugs.java.com/bugdatabase/view_bug?bug_id=6749060
如果您使用 Java = 或高于 J6u12 再次进行测试,但仍然发现该错误,您可以在 Sun 的错误数据库中的 RFE 中进行评论。
在 Java 平台中解决问题的方法是:
或者
您想要投票或评论的 Bugparade 报告在这里(如果您使用 j6u12 进行测试,它仍然存在)是
url:ho.io/jkp2
如果您想实现一个已知的解决方法,以便即使在较旧的 JRE 中文本也看起来不错,这里提供了一个
解决方法url:ho.io/jkpy
“看起来像我正在使用的解决方案通过将所需的前景色与组件的背景色混合来模拟半透明度仍然是确保使用本机光栅器的方法。”
祝你好运!
What Java version are you using? You don´t say. But apparently this has been fixed as of either Java 6 update 12 (J6u12) or JDK7 b43
See here:
https://bugs.java.com/bugdatabase/view_bug?bug_id=6749060
If your test again with Java = or higher than J6u12 and still see the bug, there´s an RFE where you can comment on at Sun´s bug database.
The way to get things fixed in the Java platform, is to either:
or
The Bugparade report you want to vote or comment in is here (in case you test with j6u12 an it´s still present) is
url: ho.io/jkp2
If you want to implement a known work-around so the text looks nice even in older JREs a work-around is provided here
url: ho.io/jkpy
"Looks like the solution that i'm using to emulate the translucency by mixing the required foreground color with the background color of the component is still the way to go to make sure that the native rasterizer is used."
Good luck!