2012-06-01 275 views
2

我想用透明背景在BufferedImage中创建一个“戒指”。我可以绘制圆形透明背景是这样的:如何使用图形对象g绘制透明形状?

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对象来做到这一点,所以我可以使用抗锯齿。

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

回答

6

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

One ring

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); 
      } 
     }); 
    } 
} 
1

您无法绘制透明形状。在包括Java 2D在内的大多数图形API中,当您绘制某些东西时,图形上下文会将现有像素与新像素“混合”。你应该找到一个混合模式来实现你正在寻找的东西。 java中的混合通过Composite完成。

应使用/实现复合执行下列操作:

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

然后,用α-绘制每个像素= 1将被共混的α-= 0,用α-像素= 1将保持相同。