Танака,
Я обнаружил, что, когда нужно использовать альфа-канал в BufferedImage, лучше всего предварительно умножить альфа-канал. Например:
// Create an ARGB image
BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
// Fill the background (for illustration)
g.setColor(Color.black);
g.fill(new Rectangle(0, 0, 512, 512));
AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
// Keep the original composite
Composite original = g.getComposite();
g.setComposite(alpha);
// Paint with transparency
Rectangle r = new Rectangle(100, 200, 50, 50);
g.setColor(Color.magenta);
g.fillRect(r);
g.setComposite(original);
// ... paint further shapes or images as necessary
// ...
g.dispose();
// Convert to a premultiplied alpha image for fast painting to a Canvas
BufferedImage biPre = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics2D gPre = biPre.createGraphics();
gPre.drawImage(bi, 0, 0, null);
gPre.dispose();
// clean up:
bi.flush();
// Now use biPre for painting to a Canvas, or a Component.
// ...
// Remember to flush it when done!
biPre.flush();
Причина для рисования сначала в TYPE_INT_ARGB заключается в том, чтобы гарантировать, что вся альфа закрашена так, как вы ожидали (не каждый раз предварительно умножается!). Затем, когда закончите, нарисуйте все изображение на TYPE_INT_ARGB_PRE, который затем сможет выводить данные на экран с хорошей скоростью.