2013-11-02 26 views
0

我在我的2D引擎中实现了图层,我希望图层可堆叠,并且我还希望能够在图层中“切割”孔 - 这意味着使用alpha。写然而,当它独立位置我似乎无法得到任何使用真实α,它通过混合的颜色试图伪造在一起,例如(我的代码):Graphics2D无法使用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)似乎没有做任何事情,但绘制黑色和复合材料是这个'伪造'的罪魁祸首,而不是覆盖FF000000(黑色)在00FFFFFF(白色无alpha)背景产生FF000000(我设置它),而不是007F7F7F(灰色没有alpha)。

我能看到的唯一原因是所有事情都经历了一个Graphics2D对象,我不能使用output.setRGB,因为它很慢,我不知道如何用它绘制自定义形状。

+2

不知道的阿尔法问题,但在绘画方式,否则不要使用ImageIO的(或任何IO)。 – camickr

+0

您需要通过'setComposite()'设置复合材料,参见不同混合模式的['AlphaComposite'](http://docs.oracle.com/javase/7/docs/api/index.html)类 – vandale

+0

@camickr为什么?它不在循环中,所以只写一次文件。 –

回答

3

您需要更改3件代码才能正常运行。

正如@vandale所说,你需要在布尔构造函数中使用具有实际alpha的颜色。 其次,alpha是不透明度(所以透明颜色应该是0)。你得到:

overlay.setColor(new Color(0x0000000, true)); 

第三,你需要说你的绘制操作实际上将覆盖任何已经在那里了(你不想在上面画(ATOP)的存在,但与透明色,而顶替(IN)那里)。你得到:

overlay.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1f)); 
+0

太棒了。有趣的是,阿尔法被颠倒了。很高兴知道这不是Graphics2D的错。 –