我正在编写带有一些自定义渲染的程序,并且需要渲染带边框的矩形。我决定简单地调用graphics2D.fillRect(),切换到边框颜色,并调用graphics2D.drawRect()。但是,即使我使用相同的坐标和大小重新调用这些调用,当我绘制的颜色是半透明的(具有alpha)时,fillRect()并不总是填充drawRect包含的整个区域。此外,fillRect()绘制的区域有时位于drawRect()包含的区域之外。为什么这两种方法在给定不同颜色时会在不同的地方绘制东西?
以下是演示此问题的示例。在窗口中单击鼠标将在使用alpha和不使用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 :(得分:3)
废弃这个答案,我重新阅读你的问题并复制你的代码并找到你所说的内容。小白线是由于绘画中的圆整误差造成的。非常有趣的小问题。在创建Graphics2D后添加它
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
渲染提示告诉绘画类您希望某些过程如何工作。我不知道为什么为颜色添加透明度会使舍入变得不同。我认为它必须与多个渲染提示结合在一起,如抗锯齿。