2011-10-09 52 views
3

繪製多邊形時,Java2D會留下右邊和底邊。我明白爲什麼這樣做。不過,我想繪製一些包含這些邊緣的東西。發生在我身上的一件事是用fillPolygondrawPolygon以相同的座標,但這似乎留下一個空白。 (查看底部的小三角形圖像。)有兩種可能性,但我無法分辨出是哪種。要啓用抗鋸齒,我這樣做:Java Graphics.fillPolygon:如何渲染右邊和底邊?

renderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 
renderHints.put(RenderingHints.KEY_RENDERING, 
       RenderingHints.VALUE_RENDER_QUALITY); 
g2d.setRenderingHints(renderHints); 

一種可能性是,抗混疊不被Alpha通道完成的,所以差距是透支造成的。在這種情況下,如果alpha通道是反混淆的,那麼邊緣會正確對接。另一種可能性是這裏有一個缺口。

我該如何解決這個問題?

此外,我不確定,但看起來多邊形輪廓可能實際上太大了。也就是說,它可能會比我想包含的右邊和底邊更遠。

謝謝。

enter image description here

- 更新 -

基於對鰻魚的氣墊船全一個很不錯的建議,我已經做了編譯例如:

import java.awt.Color; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.image.BufferedImage; 

import javax.swing.ImageIcon; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 

public class polygon { 
    private static final int WIDTH = 20; 

    public static void main(String[] args) { 
     BufferedImage img = new BufferedImage(WIDTH, WIDTH, BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g2 = img.createGraphics(); 
     int[] xPoints = {WIDTH/3, (2*WIDTH)/3, WIDTH/3}; 
     int[] yPoints = {0, WIDTH/2, WIDTH}; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setColor(Color.green); 
     g2.drawLine(0, WIDTH-1, WIDTH, WIDTH-1); 
     g2.drawLine(0, 0, WIDTH, 0); 
     g2.drawLine(WIDTH/3, 0, WIDTH/3, WIDTH); 
     g2.drawLine((2*WIDTH/3), 0, (2*WIDTH/3), WIDTH); 
     g2.setColor(Color.black); 
     g2.drawPolygon(xPoints, yPoints, xPoints.length); 
     g2.setColor(Color.black); 
     g2.fillPolygon(xPoints, yPoints, xPoints.length); 
     g2.dispose(); 

     ImageIcon icon = new ImageIcon(img); 
     JLabel label = new JLabel(icon); 

     JOptionPane.showMessageDialog(null, label); 
    } 
} 

如果離開填充多邊形紅色,你會看到下面的圖片(放大500%),這表明多邊形不會一直延伸到右邊緣。也就是說,垂直綠線對應於x=(2*WIDTH)/2,儘管紅色多邊形包含該座標,但它不會在那裏繪製任何像素。

enter image description here

要看到差距的問題,我在節目改變redblack。在這張圖片中,您可以在右下方看到一個細微的間隙,其中由drawPolygon繪製的輪廓與fillPolygon繪製的輪廓不完全吻合。

enter image description here

回答

3

向我們展示你的代碼在一個簡單的編譯執行的程序繪圖。舉例來說,當我試圖模仿你的形象和使用的RenderingHints,它似乎產生完全性右/底部邊緣適當大小的圖像:

import java.awt.Color; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.image.BufferedImage; 

import javax.swing.BorderFactory; 
import javax.swing.ImageIcon; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 

public class Foo002 { 
    private static final int WIDTH = 20; 

    public static void main(String[] args) { 
     BufferedImage img = new BufferedImage(WIDTH, WIDTH, 
      BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g2 = img.createGraphics(); 
     int[] xPoints = { WIDTH/3, (2 * WIDTH)/3, WIDTH/3 }; 
     int[] yPoints = { 0, WIDTH/2, WIDTH }; 
     g2.setColor(Color.black); 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setRenderingHint(RenderingHints.KEY_RENDERING, 
      RenderingHints.VALUE_RENDER_QUALITY); 
     g2.fillPolygon(xPoints, yPoints, xPoints.length); 
     g2.dispose(); 

     ImageIcon icon = new ImageIcon(img); 
     JLabel label = new JLabel(icon); 
     label.setBorder(BorderFactory.createLineBorder(Color.black)); 
     JPanel panel = new JPanel(); 
     panel.add(label); 

     JOptionPane.showMessageDialog(null, panel); 
    } 
} 

如果你能向我們展示了類似的計劃,重現您的問題,那麼我們可以給你更好的幫助。

+0

謝謝。我根據要求擴充了我的問題。此外,非常好的簡短例子,你在那裏。我將不得不保持這種狀態。如果我不得不自己做這件事,那麼我的無知會得到更多的代碼。 –

+0

+1'ImageIcon'! – trashgod

2

我喜歡ImageIcon的便利性,由@HFOE顯示,但是這種變化可能使它更容易看到發生了什麼。從Graphics API,即繪製一個圖形的輪廓

操作通過遍歷像素之間的 無限薄的路徑與掛起 向下的像素大小的筆和所述錨點的路徑上的右操作。 填充圖的操作通過填充該無限薄的路徑的內部來操作。

相比之下,Graphics2D必須遵循更復雜的抗鋸齒規則,從而允許它「繪製線外」。

PixelView

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.RenderingHints; 
import java.awt.image.BufferedImage; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

/** @see http://stackoverflow.com/questions/7701097 */ 
public class PixelView extends JPanel { 

    private static final int SIZE = 20; 
    private static final int SCALE = 16; 
    private BufferedImage img; 

    public PixelView(Color fill) { 
     this.setBackground(Color.white); 
     this.setPreferredSize(new Dimension(SCALE * SIZE, SCALE * SIZE)); 
     img = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g2 = img.createGraphics(); 
     int[] xPoints = {SIZE/3, (2 * SIZE)/3, SIZE/3}; 
     int[] yPoints = {0, SIZE/2, SIZE}; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setColor(Color.green); 
     g2.drawLine(0, SIZE - 1, SIZE, SIZE - 1); 
     g2.drawLine(0, 0, SIZE, 0); 
     g2.drawLine(SIZE/3, 0, SIZE/3, SIZE); 
     g2.drawLine((2 * SIZE/3), 0, (2 * SIZE/3), SIZE); 
     g2.setColor(Color.black); 
     g2.drawPolygon(xPoints, yPoints, xPoints.length); 
     g2.setColor(fill); 
     g2.fillPolygon(xPoints, yPoints, xPoints.length); 
     g2.dispose(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawImage(img, 0, 0, getWidth(), getHeight(), null); 
    } 

    private static void display() { 
     JFrame f = new JFrame("PixelView"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLayout(new GridLayout(1, 0)); 
     f.add(new PixelView(Color.black)); 
     f.add(new PixelView(Color.red)); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       display(); 
      } 
     }); 
    } 
} 
+0

我喜歡你的代碼示例。你是否試圖以任何方式回答我的問題,因爲我仍然看到輪廓和實心三角形之間的差距。我開始覺得沒有簡單的答案。 –

+0

兩者。我沒有看到任何意想不到的事情,但是你可能想用我的例子來突出顯示問題。而且,渲染可能因平臺而異;我在Mac OS X上。座標是_between_像素;一個(0,0,1,1)矩形填充一個像素,但繪製四個。 – trashgod