之间的差异。图形 fillRect 和 clearRect

Difference btw. Graphics fillRect and clearRect

当我想用半透明背景色初始化 BufferedImage 时,我注意到 fillRect 和 clearRect 之间有一些有趣的区别:

使用填充矩形:

Color someHalfTransparentColor = new Color(Integer.parseInt("77affe07", 16), true);
BufferedImage bi = new BufferedImage(10, 10, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g = bi.createGraphics();
g.setColor(someHalfTransparentColor);
g.fillRect(0, 0, 10, 10);
g.dispose();
        
System.out.println(Integer.toString(bi.getRGB(0, 0), 16));
// WORKS NOT AS EXPECTED: 77b0ff06 != 77affe07

使用 clearRect:

Color someHalfTransparentColor = new Color(Integer.parseInt("77affe07", 16), true);
BufferedImage bi = new BufferedImage(10, 10, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g = bi.createGraphics();
g.setBackground(someHalfTransparentColor);
g.clearRect(0, 0, 10, 10);
g.dispose();
        
System.out.println(Integer.toString(bi.getRGB(0, 0), 16));
// WORKS AS EXPECTED: 77affe07 == 77affe07

使用 fillRect 时,颜色值似乎略有变化。有人可以解释这种行为吗?

不同的是fillRect使用的是当前合成(getComposite) of the Graphics2D, and clearRect ignores it. By default, the composite is AlphaComposite.SrcOver。当绘制一个新的矩形时,这个合成会结合目的地的颜色和即将到达的颜色来决定最终的颜色。用一些数学来绘制。

另一方面,(至少在我的 JDK 版本中)clearRect 将合成临时设置为 AlphaComposite.Src(因此忽略当前合成),这完全忽略了目的地,然后只需将要绘制的颜色复制到所需的位置即可。

您可以看到,如果您在 fillRect 之前执行 g.setComposite(AlphaComposite.Src);,您将获得与 clearRect 相同的输出。

文档中提到这一点的部分是:

clearRect:

This operation does not use the current paint mode.

setComposite:

Sets the Composite for the Graphics2D context. The Composite is used in all drawing methods such as drawImage, drawString, draw, and fill. It specifies how new pixels are to be combined with the existing pixels on the graphics device during the rendering process.

可以这样说:

  • clearRect 不是“绘图方法”。它会擦除内容,因此 setComposite 不适用于它。
  • 合成是“绘画模式”的一部分(文档出于某种原因未定义此术语),因此 clearRect 未使用它。