2016-09-22 123 views
2

我正在嘗試和失敗,使用亞像素定位呈現在Java中的2D形狀。一個失敗的嘗試低於(暫時忽略了scaleAffineTransform):子像素渲染

import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.*; 

public class TestFrame extends Frame { 
    private static final int D = 64; 

    public static void main(String args[]) { 
     new TestFrame(D, D); 
    } 

    private final Insets ins; 
    private final double scale = 1; 

    TestFrame(int w, int h) { 
     ins = getInsets(); 
     final Dimension dim = new Dimension(w + ins.left + ins.right, h + ins.top + ins.bottom); 

     pack(); 

     addWindowListener(new WindowAdapter() { 
      @Override 
      public void windowClosing(WindowEvent we) { 
       dispose(); 
      } 
     }); 

     setSize(dim); 
     setLocationRelativeTo(null); 
     setBackground(Color.BLACK); 
     setVisible(true); 
     repaint(); 
    } 

    @Override 
    public void paint(Graphics gfx) { 
     super.paint(gfx); 
     final Graphics2D g2d = (Graphics2D)gfx; 
     g2d.setTransform(new AffineTransform(1.0/scale, 0.0, 0.0, 1.0/scale, ins.left, ins.top)); 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.setStroke(new BasicStroke((float)scale)); 
     g2d.setColor(Color.WHITE); 

     for (double deg = 0; deg < 90.0; deg += 2.0) { 
      final double rad = deg/180.0 * Math.PI; 
      final double x1 = Math.cos(rad) * D * scale; 
      final double y1 = Math.sin(rad) * D * scale; 
      final double x2 = Math.cos(rad) * (D - 4.0) * scale; 
      final double y2 = Math.sin(rad) * (D - 4.0) * scale; 
      g2d.draw(new Line2D.Double(x1, y1, x2, y2)); 
     } 
    } 
} 

這就產生了以下的輸出:

Rendering

該行應間隔均勻,但是,正如你所看到的,他們不是。我的猜測是開始和結束點正在四捨五入到最近的像素。

建議使用Line2D.Double(我已經這麼做了,顯然不起作用),或者使用AffineTransform來縮小比例。如果將代碼示例中的scale變量更改爲100,則會以更高的比例繪製線條,然後使用該變換按照建議縮小比例。這對結果圖像也沒有影響。

我在做什麼錯?

+0

沒什麼,似乎是由於舍入混合的java走樣算法......我試圖改變許多參數,最好的結果是通過改變線寬,但可惜光度滴下來...... –

+2

其實,剛嘗試'g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_PURE);'這似乎修復它。有點神祕。 –

+0

沒有試過那個! 「筆畫規範化控制提示值 - 幾何圖形應該保持不變並以亞像素精度呈現。」究竟您需要什麼或其他VALUE_STROKE_NORMALIZE? –

回答

1

將該溶液設置的呈現提示之一:

g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); 

引述Javadocs

筆劃規範化控制提示值 - 幾何應該留給未改性的和具有子像素精度渲染。