【问题标题】:How to draw a transparent shape using a Graphics object g?如何使用图形对象 g 绘制透明形状?
【发布时间】:2012-06-06 20:28:19
【问题描述】:

我想在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 对象来执行此操作,以便我可以使用抗锯齿。

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

【问题讨论】:

    标签: java image graphics awt java-2d


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2016-06-10
        • 2020-10-24
        • 2011-01-27
        • 1970-01-01
        • 2016-10-05
        • 1970-01-01
        • 2017-02-23
        • 2022-10-22
        • 2010-09-26
        相关资源
        最近更新 更多