Java淡入淡出图像

我正在尝试学习如何淡入淡出图像到另一个图像或另一个图像。 因此,如果我有2张图像,此时显示1,我想在背景中显示另一张图像,并将第一张图像淡入第二张图像。 或者,我想将焦点设置在新图像上并在第一张图像上慢慢淡入,然后停止显示第一张图像。

我不确定如何:

  1. 即使需要也能设定焦点。

  2. 如果我将alpha更改为0并递增并仅绘制一个图像,我可以淡入,但是我无法通过此代码的任何变化使其淡出。 (即评论出一幅图像)。

编辑:真的,我所担心的是能够拥有2张图像并使当前正在显示的图像慢慢消失在第2张图像中。 如何实现这一点并不需要与此相关。

这是我正在搞乱的代码示例:

import java.awt.AlphaComposite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class FadeIn extends JPanel implements ActionListener { private Image imagem; private Image image2; private Timer timer; private float alpha = 1f; public FadeIn() { imagem = (new ImageIcon(getClass().getResource( "/resources/1stImage.jpg"))).getImage(); image2 = (new ImageIcon(getClass().getResource( "/resources/2ndImage.jpg"))).getImage(); timer = new Timer(20, this); timer.start(); } // here you define alpha 0f to 1f public FadeIn(float alpha) { imagem = (new ImageIcon(getClass().getResource( "/resources/1stImage.jpg"))).getImage(); this.alpha = alpha; } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.drawImage(imagem, 0, 0, 400, 300, null); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); g2d.drawImage(image2, 0, 0, 400, 300, null); } public static void main(String[] args) { JFrame frame = new JFrame("Fade out"); frame.add(new FadeIn()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(420, 330); // frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } @Override public void actionPerformed(ActionEvent e) { alpha += -0.01f; if (alpha <= 0) { alpha = 0; timer.stop(); } repaint(); } } 

基本上,这样做是使用相同的alpha值,从0-1逐渐消失,然后使用相同的alpha,从1-0开始,允许两个图像交叉淡入淡出…

衰退

魔术基本上发生在paintComponent ,使用alpha值和传出图像进入的图像使用1f - alpha

在两个图像之间切换实际上是一个相同的过程,期望将inImage交换为outImage

时机略有不同。 这使用基于时间的算法,而不是使用标准增量(例如0.01 )从0-1直接移动。

也就是说,我使用一个每40毫秒左右滴答一次的计时器,然后根据计时器运行的时间进行计算并相应地计算alpha值…

这允许你改变动画将花费的时间,但也提供了一个稍好的算法,考虑到Swings渲染引擎的被动性质……

 import java.awt.AlphaComposite; 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.event.MouseAdapter; import java.awt.event.MouseEvent; 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 FadeImage { public static void main(String[] args) { new FadeImage(); } public FadeImage() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public static class TestPane extends JPanel { public static final long RUNNING_TIME = 2000; private BufferedImage inImage; private BufferedImage outImage; private float alpha = 0f; private long startTime = -1; public TestPane() { try { inImage = ImageIO.read(new File("/path/to/inImage")); outImage = ImageIO.read(new File("/path/to/outImage")); } catch (IOException exp) { exp.printStackTrace(); } final Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (startTime < 0) { startTime = System.currentTimeMillis(); } else { long time = System.currentTimeMillis(); long duration = time - startTime; if (duration >= RUNNING_TIME) { startTime = -1; ((Timer) e.getSource()).stop(); alpha = 0f; } else { alpha = 1f - ((float) duration / (float) RUNNING_TIME); } repaint(); } } }); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { alpha = 0f; BufferedImage tmp = inImage; inImage = outImage; outImage = tmp; timer.start(); } }); } @Override public Dimension getPreferredSize() { return new Dimension( Math.max(inImage.getWidth(), outImage.getWidth()), Math.max(inImage.getHeight(), outImage.getHeight())); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.setComposite(AlphaComposite.SrcOver.derive(alpha)); int x = (getWidth() - inImage.getWidth()) / 2; int y = (getHeight() - inImage.getHeight()) / 2; g2d.drawImage(inImage, x, y, this); g2d.setComposite(AlphaComposite.SrcOver.derive(1f - alpha)); x = (getWidth() - outImage.getWidth()) / 2; y = (getHeight() - outImage.getHeight()) / 2; g2d.drawImage(outImage, x, y, this); g2d.dispose(); } } }