高さと幅が等しいdrawOvalメソッドを使用してみましたが、直径が大きくなると、円の見た目が悪くなります。サイズに関係なく、まともな円を描くにはどうすればよいですか。 Javaまたはその他の方法でアンチエイリアスをどのように実装しますか?.
結局のところ、Java2D(私があなたが使用しているものと想定しています)はすでにこれでかなり優れています!ここにはまともなチュートリアルがあります: http://www.javaworld.com/javaworld/jw-08-1998/jw-08-media.html
重要な行は次のとおりです。
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
レンダリングのヒントを設定できます:
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
役立つ2つのこと:
Java.awt.geom.Ellipse2D
_ではなく_Graphics.drawOval
_のインスタンスでGraphics2D.draw(Shape)
を使用します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);
}
_
setRenderingHint
の例については、Josefの回答を参照してください
もちろん、半径を必要なものに設定します。
@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);
}
バグレポートを指摘してくれたOleg Estekhinに感謝します。方法を説明しているからです。
これは前後の小さな円です。ピクセルグリッドを表示するために数倍に拡大します。
行を下に行くと、サブピクセルの量だけわずかに移動しています。
最初の列には、レンダリングのヒントがありません。 2つ目はアンチエイリアスのみです。 3つ目は、アンチエイリアスと純粋モードです。
アンチエイリアスのヒントのみで、最初の3つの円は同じで、最後の2つの円も同じであることに注意してください。いくつかの個別の遷移が発生しているようです。おそらくある時点で丸められます。
これがコードです。読みやすくするために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"))
概要:両方が必要ですVALUE_ANTIALIAS_ON
およびVALUE_STROKE_PURE
サブピクセル精度で描かれた適切に見える円を取得します。
「まともな円」を描画できないことは、非常に古いバグ 6431487 に関連しています。
アンチエイリアスをオンにしてもあまり効果はありません。必要な円のサイズが16ピクセル(アイコンのサイズとしてかなり一般的)で、アンチエイリアスがオンになっているときに、drawOval()またはdrawShape(Eclipse)によって生成される「円」の種類を確認してください。アンチエイリアス処理された大きな円は見栄えがよくなりますが、誰かがそれらを注意深く見たい場合は、非対称です。
「まともな円」を描くには、手動で描く必要があるようです。アンチエイリアスを使用しない場合、中点円アルゴリズムになります(この 質問 は、かなりのJavaコードを使用して)回答します)。