2013-08-02 55 views
0

我正在繪製徑向漸變的小圓圈。結果示例(r = 10像素):爲什麼這個RadialGradientPaint繪製不正確?

r=10

但是,當我減少半徑,奇怪的事情開始發生。如果r = 5px的:

r=5

縮放,以匹配10px的形象:

r=5,scaled

它變得更糟如果r = 2px的(再次,縮放):

enter image description here

如您所見,漸變的中心始終關閉(do wn和右邊)從圈子的中心。

我用於生成上述圖像的代碼(SSCCE,編譯&可運行):

import java.awt.image.*; 
import javax.imageio.ImageIO; 
import java.io.File; 
import java.awt.*; 
import java.awt.geom.*; 

public class Test { 
    public static void main(String[] args) throws Exception { 
     float r = 2; 
     BufferedImage img = new BufferedImage((int) r*4, (int) r*4, BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g = img.createGraphics(); 
     RenderingHints rh = new RenderingHints(null); 
     rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     rh.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); 
     rh.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); 
     rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
     g.addRenderingHints(rh); 
     g.setBackground(Color.WHITE); 
     g.clearRect(0, 0, (int) r*4, (int) r*4); 
     g.setPaint(new RadialGradientPaint(
      r*2,r*2,r*2, 
      new float[] {0.1f,0.35f}, 
      new Color[] {Color.RED, Color.GREEN} 
     )); 
     g.fill(new Ellipse2D.Float(r,r,r*2,r*2)); 
     g.dispose(); 
     ImageIO.write(img, "png", new File("out.png")); 
    } 
} 

我試圖切換呈現提示,但結果並不改變。什麼可能導致這個問題?

編輯:

抵消的RadialGradientPaint通過在正確的圖像0.5f左上結果(R = 2):

enter image description here

「固定」 的代碼:

g.setPaint(new RadialGradientPaint(
    r*2-0.5f, r*2-0.5f, r*2, 
    new float[] {0.1f,0.35f}, 
    new Color[] {Color.RED, Color.GREEN} 
)); 

回答

1

問題與你的圈子的高度和寬度是偶數有關。您曾經有g.fill(new Ellipse2D.Float(r,r,r*2,r*2)); 作爲您的代碼的一部分。這使得你的圈子的寬度和高度始終均勻。這會導致問題,因爲計算機不完美,並且不可能精確地在具有均勻維度的圓的中心繪製像素。爲了解決這個問題,我添加了一個到你畫圈的地方。工作代碼如下:

import java.awt.image.*; 
import javax.imageio.ImageIO; 
import java.io.File; 
import java.awt.*; 
import java.awt.geom.*; 

public class Test { 
    public static void main(String[] args) throws Exception { 
     float r = 2; 
     BufferedImage img = new BufferedImage((int) r*4 + 1, (int) r*4 + 1, BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g = img.createGraphics(); 
     RenderingHints rh = new RenderingHints(null); 
     rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     rh.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); 
     rh.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); 
     rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
     g.addRenderingHints(rh); 
     g.setBackground(Color.WHITE); 
     g.clearRect(0, 0, (int) r*4 + 1, (int) r*4 + 1); 
     g.setPaint(new RadialGradientPaint(
      r*2,r*2,r*2, 
      new float[] {0.1f,0.35f}, 
      new Color[] {Color.RED, Color.GREEN} 
     )); 
     g.fill(new Ellipse2D.Float(r,r,r*2 + 1,r*2 + 1)); 
     g.dispose(); 
     ImageIO.write(img, "png", new File("out.png")); 
    } 
} 
+0

是的,我同意像素問題 - 但爲什麼同樣發生抗鋸齒?反鋸齒是否意味着解決這個問題? – Rogach

+0

它確實但抗鋸齒只能使邊緣看起來更平滑。 Java仍然需要找到一個地方來放置圓的中心和邊緣的大小,但不可能把它放在正確的中心,所以Java把中心放在不太精確的中心。 – Tiger

+0

這不是真的 - 請參閱我的新編輯(將漸變中心偏移0.5f以產生完美居中的漸變效果)。 – Rogach