我正在我的2D引擎中实现图层,我希望图层可以叠加,我还想要一个在图层中“切洞”的功能 - 这意味着使用alpha。然而,当单独编写它时我似乎无法使用真正的alpha,它试图通过混合颜色来伪造它,例如(我的代码):
BufferedImage background, foreground;
public GraphicsTest() {
background = new BufferedImage(500,500,BufferedImage.TYPE_INT_ARGB);
foreground = new BufferedImage(500,500,BufferedImage.TYPE_INT_ARGB); // Fully capable of alpha.
Random r = new Random();
int white = Color.white.getRGB();
// Draw random white dots
for (int i=0; i<500; i++) {
int
x = r.nextInt(500),
y = r.nextInt(500);
background.setRGB(x, y, white);
}
}
@Override
protected void paintComponent(Graphics g) {
BufferedImage output = new BufferedImage(500,500,BufferedImage.TYPE_INT_ARGB); // Fully capable of alpha.
Graphics2D canvas = output.createGraphics();
Graphics2D overlay = foreground.createGraphics();
canvas.drawImage(background, 0, 0, null);
overlay.setColor(Color.white);
overlay.fillRect(0, 0, 500, 500);
// Start drawing with alpha
overlay.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
overlay.setColor(new Color(0xFF000000)); // Overwrite/draw full alpha, colour doesn't matter when alpha is 100%
overlay.fillRect(100, 100, 125, 87);
//canvas.setColor(Color.red);
//canvas.fillRect(0, 0, 500, 500);
canvas.drawImage(foreground, 0, 0, null);
overlay.dispose();
canvas.dispose();
g.drawImage(output, 0, 0, null);
// Also write to a file for manual raw pixel checking
try {
// Does output a 32-bit depth image
ImageIO.write(output, "PNG", new File("c:/output.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
这是我能想到的最基本的测试,我有两个图像,一个用于背景,一个用于前景,我需要在127x87(随机大小)框中通过前景看到背景。 目前它会产生带有黑框的白色屏幕,背框应该是背景的一部分。
我在这里试过各种各样的方法,设置复合材料并用完整的alpha绘制黑色但是在组合时我从未看到背景,setColor(0xFF000000)似乎没有做任何事情,只是绘制黑色而复合材料是这个'假装'的罪魁祸首,而不是在00FFFFFF(白色没有alpha)背景上覆盖FF000000(黑色),产生FF000000(我设置它),而不是007F7F7F(灰色没有alpha)。
我能看到的唯一原因是所有东西都是通过Graphics2D对象,我不能使用output.setRGB,因为它很慢,我不知道如何用它绘制自定义形状。
答案 0 :(得分:3)
您需要更改3项内容才能使代码正常运行。
正如@vandale所说,你需要使用带有布尔构造函数的实际alpha颜色。 其次,alpha是不透明度(因此透明色应为0)。你得到:
overlay.setColor(new Color(0x0000000, true));
第三,你需要说你的绘画操作实际上会覆盖已经存在的东西(你不想在现有的顶部(ATOP)上绘制,而是用透明颜色(IN)代替那里的东西) 。你得到:
overlay.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1f));