2013-05-01 1 views
4

일부 사용자 정의 렌더링이있는 프로그램을 작성 중이었고 테두리가있는 사각형을 렌더링해야했습니다. 필자는 단순히 graphics2D.fillRect()를 호출하고 테두리 색상으로 전환하고 graphics2D.drawRect()를 호출하기로 결정했습니다. 그러나, 같은 좌표와 크기로이 호출을 되 돌리지 만, drawRect에 포함 된 전체 영역을 fillRect()가 채울 때 반투명 (알파가 있음) 할 때 fillRect()가 항상 채워지지는 않습니다. 게다가, fillRect()에 의해 그려지는 영역은 때로는 drawRect()에 의해 포함 된 영역 밖에 있습니다. 왜이 두 가지 방법은 다른 색상이 주어지면 다른 장소에서 물건을 그립니다.Java graphics2D fillRect가 반투명 색상으로 제대로 작동하지 않습니다.

다음은이 문제를 보여주는 예제입니다. 창에서 마우스를 클릭하면 채우기를 알파와 없음으로 전환합니다. 알파를 사용하여 그릴 때 흰색 아래에있는 사각형의 아래쪽에 픽셀 행이 있지만 알파없이 그릴 때 그 픽셀 행은 없습니다.

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의 버그 인 것 같습니다. – lbalazscs

답변

3

스크랩 그 대답은 귀하의 질문을 다시 읽고 귀하의 코드를 복사하여 귀하의 이야기를 발견했습니다. 작은 흰색 선은 그림에서 반올림 오류가 발생했기 때문입니다. 아주 재미있는 작은 문제.

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

렌더링 힌트가 특정 절차가 작동하는 방법을 그림 클래스에게 당신의 Graphics2D를 생성 한 후이를 추가합니다. 색상에 투명도를 추가하면 왜곡이 다른지 알 수 없습니다. 나는 그것이 안티 앨리어싱과 같이 결합 된 여러 렌더링 힌트들과 관련이있을 것이라고 생각한다.

+0

이것은 알파 합성에 대한 유용한 정보이지만 유감 스럽지만 문제가 해결되지 않습니다. –

+0

@EricFitting 저는 투명도를 얻기 위해 알파와 함께 색상 대신 알파 합성을 사용하는 것이 좋겠다고 생각합니다. 그것은 작동하지 않거나 이것은 당신을위한 실현 가능한 해결 방법이 아니겠습니까? – lbalazscs

+0

@lbalazscs 작동하지 않았습니다. hasAlpha가 true 일 때 직사각형의 아래쪽에 채워지지 않은 픽셀의 동일한 줄이 보입니다. –

관련 문제