如何在Java中绘制一个像样的圆圈

sol*_*oth 24 java graphics geometry antialiasing

我尝试使用drawOval方法具有相同的高度和宽度,但随着直径的增加,圆圈变得更糟.无论大小如何,我能做些什么才能拥有体面的圆圈.我如何在java或其他方法中实现抗锯齿.

Bra*_*ugh 45

事实证明,Java2D(我假设你正在使用的)已经相当不错了!这里有一个不错的教程:http://www.javaworld.com/javaworld/jw-08-1998/jw-08-media.html

重要的是:

graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                          RenderingHints.VALUE_ANTIALIAS_ON);
Run Code Online (Sandbox Code Playgroud)

  • 看起来常量已从Graphics2D移到RenderingHints.参见[本例](http://www.java2s.com/Code/JavaAPI/java.awt/Graphics2DsetRenderingHintKeyhintKeyObjecthintValue.htm). (16认同)
  • 你必须爱上11岁的联系,希望他们永远不会死. (4认同)
  • 19年仍在计算= P. (4认同)
  • 20岁还活着!:ㅇ (2认同)
  • 没有。找不到网页 (2认同)

Jos*_*ger 29

您可以设置渲染提示:

Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);
Run Code Online (Sandbox Code Playgroud)


fin*_*nnw 13

有两件事可能会有所帮助:

  1. Graphics2D.draw(Shape)与实例一起使用java.awt.geom.Ellipse2D而不是Graphics.drawOval
  2. 如果结果仍不理想,请尝试使用Graphics2D.setRenderingHint启用抗锯齿功能

public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    Shape theCircle = new Ellipse2D.Double(centerX - radius, centerY - radius, 2.0 * radius, 2.0 * radius);
    g2d.draw(theCircle);
}
Run Code Online (Sandbox Code Playgroud)

请参阅Josef的答案 setRenderingHint


Cli*_*int 6

当然,您可以根据需要设置半径:

@Override
public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    Ellipse2D.Double hole = new Ellipse2D.Double();
    hole.width = 28;
    hole.height = 28;
    hole.x = 14;
    hole.y = 14;
    g2d.draw(hole);
}
Run Code Online (Sandbox Code Playgroud)


Evg*_*eev 6

感谢 Oleg Estekhin 指出错误报告,因为它解释了如何去做。

这里有一些之前和之后的小圆圈。放大几倍以查看像素网格。

之前和之后的圆圈

向下一行,它们以亚像素数量轻微移动。

第一列没有渲染提示。第二种是仅使用抗锯齿。第三种是抗锯齿和纯模式。

请注意仅使用抗锯齿提示如何,前三个圆圈相同,后两个圆圈也相同。似乎发生了一些离散的转变。可能在某个时候四舍五入。

这是代码。它位于 Jython 中以提高可读性,但它驱动底层的 Java 运行时库,并且可以无损地移植到等效的 Java 源代码,具有完全相同的效果。

from java.lang import *
from java.io import *
from java.awt import *
from java.awt.geom import *
from java.awt.image import *
from javax.imageio import *

bim = BufferedImage(30, 42, BufferedImage.TYPE_INT_ARGB)
g = bim.createGraphics()
g.fillRect(0, 0, 100, 100)
g.setColor(Color.BLACK)
for i in range(5):
    g.draw(Ellipse2D.Double(2+0.2*i, 2+8.2*i, 5, 5))

g.setRenderingHint( RenderingHints.  KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON)

for i in range(5):
    g.draw(Ellipse2D.Double(12+0.2*i, 2+8.2*i, 5, 5))

g.setRenderingHint( RenderingHints.  KEY_STROKE_CONTROL,
                    RenderingHints.VALUE_STROKE_PURE)

for i in range(5):
    g.draw(Ellipse2D.Double(22+0.2*i, 2+8.2*i, 5, 5))

#You'll probably want this too later on:
#g.setRenderingHint( RenderingHints.  KEY_INTERPOLATION,
#                    RenderingHints.VALUE_INTERPOLATION_BICUBIC)
#g.setRenderingHint( RenderingHints.  KEY_RENDERING, 
#                    RenderingHints.VALUE_RENDER_QUALITY)

ImageIO.write(bim, "PNG", File("test.png"))
Run Code Online (Sandbox Code Playgroud)

总结:您需要VALUE_ANTIALIAS_ONVALUE_STROKE_PURE才能获得以亚像素精度绘制的正确外观的圆圈。