2013-05-01 359 views
4

我正在寫一個自定義渲染的程序,並需要渲染帶邊框的矩形。我決定簡單地調用graphics2D.fillRect(),切換到邊框顏色,並調用graphics2D.drawRect()。但是,即使我使用相同的座標和大小背靠背進行調用,但當我繪製的顏色是半透明(具有alpha)時,fillRect()並不總是填充drawRect包含的整個區域。此外,由fillRect()繪製的區域有時在drawRect()所包含的區域之外。爲什麼這兩種方法在不同的地方繪製不同顏色的東西?Java的graphics2D fillRect不能正常工作與半透明的顏色

下面是一個演示問題的例子。點擊窗口中的鼠標將在用alpha和不用繪製填充之間切換。請注意,當使用alpha繪圖時,矩形底部有一行像素爲白色,但在繪製不帶alpha的繪圖時,該行像素不在此處。

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.geom.AffineTransform; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 


public class ColorWithAlpha extends JPanel { 

private boolean hasAlpha = true; 

private static final long serialVersionUID = 1L; 

/** 
* @param args 
*/ 
public static void main(String[] args) { 
    // setup a basic frame with a ColorWithAlpha in it 
    JFrame frame = new JFrame(); 
    JPanel panel = new ColorWithAlpha(); 
    panel.setPreferredSize(new Dimension(500, 500)); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.add(panel); 
    frame.pack(); 
    frame.show(); 
} 

public ColorWithAlpha() { 
    super(); 
    setBackground(Color.WHITE); 

    this.addMouseListener(new MouseListener() { 
     @Override 
     public void mouseClicked(MouseEvent arg0) { 
      // when the user clicks their mouse, toggle whether we are drawing a color with alhpa or without. 
      hasAlpha = !hasAlpha; 
      ColorWithAlpha.this.repaint(); 
     } 
     @Override 
     public void mouseEntered(MouseEvent arg0) {} 

     @Override 
     public void mouseExited(MouseEvent arg0) {} 

     @Override 
     public void mousePressed(MouseEvent arg0) {} 

     @Override 
     public void mouseReleased(MouseEvent arg0) {} 
    }); 
} 

@Override 
public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    Color color = new Color(100, 100, 250);// this color doesnt have an alpha component 

    // some coordinates that demonstrate the bug. Not all combinations of x,y,width,height will show the bug 
    int x = -900; 
    int y = 1557; 
    int height = 503; 
    int width = 502; 
    if (hasAlpha) { // toggle between drawing with alpha and without 
     color = new Color(200, 100, 250, 100); 
    } 
    Graphics2D g2 = (Graphics2D) g; 
    // this is the transform I was using when I found the bug. 
    g2.setTransform(new AffineTransform(0.160642570281124, 0.0, 0.0, -0.160642570281124, 250.0, 488.0)); 


    g2.setColor(color); 
    g2.fillRect(x, y, width, height); 
    g2.setColor(Color.DARK_GRAY); 
    g2.setStroke(new BasicStroke(8f)); 
    g2.drawRect(x, y, width, height); 

} 
} 
+0

似乎是Java 2D中的一個bug。 – lbalazscs 2013-05-02 15:31:08

回答

3

廢話回答,我重讀你的問題並複製你的代碼,並找到你在說什麼。小的白線是由於繪畫中的舍入誤差造成的。非常有趣的小問題。在創建Graphics2D之後添加此項

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

渲染提示告訴繪畫類您希望某些過程如何工作。我不知道爲什麼增加顏色的透明度會使舍入不同。我認爲它必須與多重渲染提示結合在一起,如抗鋸齒。

+0

這是關於alpha合成的有用信息,但不幸的是它並沒有爲我解決問題。 – 2013-05-02 13:11:15

+0

@EricFitting我想這個想法是使用alpha合成而不是使用alpha來實現透明度的顏色。它不起作用,或者這對你來說不是一個可行的解決方法? – lbalazscs 2013-05-02 15:32:48

+0

@lbalazscs它沒有工作。當hasAlpha爲true時,我會在矩形底部看到相同的未填充像素線。 – 2013-05-02 16:10:51