How to draw a decent looking Circle in Java

前端 未结 7 1351
我在风中等你
我在风中等你 2020-11-27 06:20

I have tried using the method drawOval with equal height and width but as the diameter increases the circle becomes worse looking. What can I do to have a decent looking cir

相关标签:
7条回答
  • 2020-11-27 06:58

    Thanks to Oleg Estekhin for pointing out the bug report, because it explains how to do it.

    Here are some small circles before and after. Magnified a few times to see the pixel grid.

    Circles before and after

    Going down a row, they're moving slightly by subpixel amounts.

    The first column is without rendering hints. The second is with antialias only. The third is with antialias and pure mode.

    Note how with antialias hints only, the first three circles are the same, and the last two are also the same. There seems to be some discrete transition happening. Probably rounding at some point.

    Here's the code. It's in Jython for readability, but it drives the Java runtime library underneath and can be losslessly ported to equivalent Java source, with exactly the same effect.

    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"))
    

    Summary: you need both VALUE_ANTIALIAS_ON and VALUE_STROKE_PURE to get proper looking circles drawn with subpixel accuracy.

    0 讨论(0)
提交回复
热议问题