AlphaComposite透明度与重绘重叠为黑色

时间:2013-04-14 06:15:37

标签: java graphics alpha repaint drawimage

所以我在另一个面板上面有一个图像,并且该图像是透明的,因此您可以看到它下面的面板。我要做的是使用repaint()淡化图像(使用java.awt.Graphics中的drawImage()方法绘制),直到它完全透明,这样你就可以清楚地看到它下面的面板。截至目前,图像只是淡入黑色而不是透明纹理。

这是我现在的一些代码:

paintComponent方法:

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    float alpha = 1f-(.01f*(float)opcounter);
    Graphics2D g2d = (Graphics2D)g;
    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha);
    g2d.drawImage(img, 0, 0, null);
}

为计时器

调用的actionPerformed方法
public void actionPerformed(ActionEvent e)
{
    opcouner++;
    panel.repaint();
}

我的代码的更长(无凝聚)版本:(包括paintComponent和计时器的Mover类)

                            public void paintComponent(Graphics g)
            {   
                super.paintComponent(g);
                Dimension framesize = frame.getSize();
                this.setBounds(0,0,framesize.width, framesize.height-61);

                if (buff)
                {
                    //this.add(buffer);
                    if (opcounter <= 255)
                    {
                        buffer.setForeground(new Color(250, 250, 250, 0+opcounter));
                    }
                    else 
                    {
                        opcounter = 0;
                        buff = false;
                        hand = true;
                    }
                }
                if (hand)
                {
                    this.add(handson);
                    if (opcounter <= 255)
                    {
                        handson.setForeground(new Color(250, 250, 250, 0+opcounter));
                    }
                    else 
                    {
                        opcounter = 0;
                        hand = false;
                        log = true;
                    }
                }
                if (log)
                {
                    this.add(logic);
                    if (opcounter <= 255)
                    {
                        logic.setForeground(new Color(250, 250, 250, 0+opcounter));
                    }
                    else 
                    {
                        opcounter = 0;
                        log = false;
                        pan = true;
                    }
                }
                if (pan)
                {
                    this.add(panic);
                    if (opcounter <= 255)
                    {
                        panic.setForeground(new Color(250, 250, 250, 0+opcounter));
                    }
                    else 
                    {
                        opcounter = 0;
                        pan = false;
                        first = false;
                        second = true;
                        try
                        {
                            //Thread.sleep(2000);
                        }
                        catch(Exception e)
                        {
                            System.out.println("thread not slept");
                        }
                        System.out.println("opcounter = " + opcounter);
                        black.setVisible(false);
                        handson.setVisible(false);
                        logic.setVisible(false);
                        panic.setVisible(false);
                        tutpic = true;
                    }
                }
                if (tutpic)
                {
                    if (opcounter <= 200)
                    {
                        Graphics2D g2d = (Graphics2D)g.create();
                        float alpha = 1f-(.01f*(float)opcounter);
                                          g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha));
                        g2d.drawImage(tut, 0, 0, null);
                        g2d.dispose();
                    }
                    else
                    {
                        opcounter = 0;
                        tutpic = false;
                    }
                }
            }

            class Mover implements ActionListener
            {
                public void actionPerformed(ActionEvent e)
                {
                    if (!tutpic)
                        opcounter+=4;
                    else
                    {
                        opcounter++;
                    }
                    tutorial.repaint();
                }   
            }

任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:3)

您需要在Graphics方法存在之前恢复paintComponent上下文的状态。这非常重要,因为Graphics上下文是共享资源,所有需要更新的组件都将被赋予相同的Graphics,所以现在组件绘制后的每个组件都将共享一些AlphaComposite ...

更好的解决方案是创建Graphics上下文的临时副本,应用您想要的任何设置并在完成后处理它。这将确保您在Graphics背景下所做的更改将在该方法存在后继续进行...

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    float alpha = 1f-(.01f*(float)opcounter);
    // Create your own copy...
    Graphics2D g2d = (Graphics2D)g.create();
    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha);
    g2d.drawImage(img, 0, 0, null);
    // Don't forget to dispose of it
    g2d.dispose();
}

记住,你创造它,你处理它!

<强>更新

尝试使用AlphaComposite.SRC_OVER代替......

enter image description here

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestFadeOut {

    public static void main(String[] args) {
        new TestFadeOut();
    }

    public TestFadeOut() {
        EventQueue.invokeLater(
                        new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private float alpha = 1f;
        private float diff = -0.02f;
        private BufferedImage img;

        public TestPane() {
            try {
                img = ImageIO.read(new File("C:\\Users\\swhitehead\\Documents\\My Dropbox\\Ponies\\url.png"));
                Timer timer = new Timer(40, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        alpha += diff;
                        if (alpha < 0) {
                            diff *= -1;
                            alpha = diff;
                        } else if (alpha > 1f) {
                            diff *= -1;
                            alpha = 1f + diff;
                        }
                        repaint();
                    }
                });
                timer.setRepeats(true);
                timer.setCoalesce(true);
                timer.start();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (img != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
                int x = getWidth() - img.getWidth();
                int y = getHeight() - img.getHeight();
                g2d.drawImage(img, x, y, this);
                g2d.dispose();
            }
        }
    }
}

查看Composting Graphics了解更多详情......