如何使用Graphics对象绘制透明形状?

我想在具有透明背景的BufferedImage创建一个“环”。 我可以用这样的透明背景绘制圆圈:

 BufferedImage bi = new BufferedImage(d, d, BufferedImage.TYPE_INT_ARGB); Graphics2D g = (Graphics2D) bi.getGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(c); g.fillOval(0, 0, d, d); 

但是现在我想在它的中间绘制一个较小的透明圆圈来制作一个圆环(所以当我在另一个图像上绘制这个图像时,环形周围和内部的像素都不会被绘制)。 我想使用Graphics对象来执行此操作,以便我可以使用抗锯齿。

这可能吗? 如果不是,那么解决这个问题的最佳方法是什么?

创建一个圆形形状,然后从中减去另一个圆形形状,将其设置为剪辑,最后可能需要沿着所需的线条。 要隐藏剪辑的粗糙边缘,请绘制形状的2px宽笔触。

一枚戒指

 import java.awt.*; import java.awt.geom.*; import java.awt.image.BufferedImage; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.*; public class OneRing { OneRing(BufferedImage imageBG, BufferedImage imageFG) { // presumes the images are identical in size BNI int w = imageBG.getWidth(); int h = imageBG.getHeight(); Ellipse2D.Double ellipse1 = new Ellipse2D.Double( w/16,h/16,7*w/8,7*h/8); Ellipse2D.Double ellipse2 = new Ellipse2D.Double( w/4,h/4,w/2,h/2); Area circle = new Area(ellipse1); circle.subtract(new Area(ellipse2)); Graphics2D g = imageBG.createGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g.setClip(circle); g.drawImage(imageFG, 0, 0, null); g.setClip(null); Stroke s = new BasicStroke(2); g.setStroke(s); g.setColor(Color.BLACK); g.draw(circle); g.dispose(); JLabel l = new JLabel(new ImageIcon(imageBG)); JOptionPane.showMessageDialog(null, l); } public static void main(String[] args) throws Exception { URL urlFG = new URL("http://i.stack.imgur.com/OVOg3.jpg"); URL urlBG = new URL("http://i.stack.imgur.com/lxthA.jpg"); final BufferedImage biFG = ImageIO.read(urlFG); final BufferedImage biBG = ImageIO.read(urlBG); SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { new OneRing(biBG, biFG); } }); } } 

您无法绘制透明形状。 在大多数图形API(包括Java 2D)中,当您在某些内容上绘制时,图形上下文会将现有像素与新像素“混合”。 您应该找到一种可以实现您所需要的混合模式。 java中的混合是通过Composite完成的。

您应该使用/实现一个复合执行以下操作:

 result color = destination color result alpha = destination alpha - source alpha 

然后,您使用alpha = 1绘制的每个像素将混合为alpha = 0,而alpha = 1的像素将保持不变。