首页 > 解决方案 > 顺便说一句,差异。图形 fillRect 和 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 时颜色值略有变化。有人可以解释这种行为吗?

标签: javaimagegraphicsawtbufferedimage

解决方案


不同之处在于fillRect使用 的当前复合 ( getComposite) Graphics2D,并clearRect忽略它。默认情况下,复合是AlphaComposite.SrcOver. 当绘制一个新的矩形时,这个合成将通过结合目的地的颜色和将要绘制的颜色与一些数学来决定最终的颜色。

另一方面,(至少在我的 JDK 版本上)clearRect将组合临时设置为AlphaComposite.Src(因此忽略当前组合),这完全忽略了目的地,只是将您想要绘制的颜色复制到您想要的位置。

您可以看到,如果您g.setComposite(AlphaComposite.Src);之前这样做fillRect,您将获得与clearRect.

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

clearRect

此操作不使用当前的绘制模式。

setComposite

设置 Graphics2D 上下文的 Composite。Composite 用于所有绘图方法,例如drawImagedrawStringdrawfill。它指定在渲染过程中如何将新像素与图形设备上的现有像素组合。

可以这样说:

  • clearRect不是“绘图方法”。它会擦除事物,因此setComposite不适用于它。
  • 合成是“绘画模式”的一部分(文档由于某种原因没有定义这个术语),所以clearRect不使用它。

推荐阅读